在2D M x N网格中发现封闭空间的存在

时间:2018-11-24 12:16:36

标签: algorithm

我的任务是使用算法在问题提供的网格中找到封闭空间的存在。空格('')表示有孔,而井号('#')表示有墙。现在假设我有一个二维的M x N网格,如何查找是否存在封闭的空间?带有封闭空间的网格示例:

########
#      #
#      #
#      #
#      #
#      #
#      #
########

########
#      #
#      #
########
#      #
#      #
#       
########

########
# #    #
# #    #
# ######
#      #
#      #
#       
########

########
##     #
# #    #
#  #   #
#   #  #
#    # 
#     # 
########

起初,我试图将此网格存储到字符串向量中。然后,我继续检查每个空格是一个哈希还是一个空格。如果是一个空间(现在将其位置称为initial),我将检查该空间的周围区域,直到找到从所述initial的边缘可以到达的孔(空间)。如果是散列,我将继续网格中的下一个“正方形”。

但是,我尝试仅对每种可能性进行暴力破解的算法似乎非常乏味且效率低下。在继续执行此任务之前,我是否应该了解其他一些概念(阅读有关地图,路径,树木等的更多信息)。如果有的话,您能给我先读些什么吗?如果没有,您能指导我吗?

我解决这个任务的方法正确吗?

1 个答案:

答案 0 :(得分:1)

想法是:

  • 我们从每个未访问的空白单元格开始
  • 尝试访问所有连接的空单元格
  • 如果我们可以到达边界,那么这不是封闭区域
  • 如果连接区域的任何一个单元格都不是边界单元格,则该区域将被壁围住,我们不加计数。

这是c++中的示例实现,它计算了封闭区域的数量:

#include <string.h>
#include <cstdio>

// m is row_num, n is column_num
int m, n;
// grid
char grid[5005][5005];
// direction arrays
int R[] = {0, -1, 0, 1};
int C[] = {1, 0, -1, 0};
// check for weather we reach boundary or not
// and visit array
bool wentToBoundary, vis[5005][5005];

// DFS implementation of 2D grid
void dfs(int x, int y) {
    // visit the cell grid[x][y] as true
    vis[x][y] = true;

    // if the curren cell is a boundary cell, then mark that
    // we reach to boundary from an inner cell
    if (x == 0 || x == m -1 || y == 0 || y == n - 1)
        wentToBoundary = true;

    // try to go in all 4 direction (right, up, left, down)
    // if the cell is not visited yet and contans ' '
    for (int i = 0; i < 4; i++) {
        int xx = x + R[i];
        int yy = y + C[i];

        if (xx >=0 && xx < m && yy >= 0 && yy < n) {
            if (!vis[xx][yy] && grid[xx][yy] == ' ')
                dfs(xx, yy);
        }
    }
}

int main() {
    // input the grid size;
    scanf("%d %d", &m, &n);
    getchar();

    // input the grid
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%c", &grid[i][j]);
        }
        getchar();
    }

    // initialize
    int spaceEnclosedCount = 0;
    memset(vis, false, sizeof(vis));

    // iterate only for inner cells not the boundary cells
    for (int i = 1; i < m - 1; i++) {
        for (int j = 1; j < n - 1; j++) {
            if (!vis[i][j] && grid[i][j] == ' ') {
                wentToBoundary = false;
                dfs(i, j);

                if (!wentToBoundary) {
                    spaceEnclosedCount++;
                }
            }
        }
    }

    printf("number of area enclosed by spaces: %d\n", spaceEnclosedCount);

    return 0;
}