C++ 在网格中查找加号的算法

C++ 在网格中查找加号的算法,c++,algorithm,grid,breadth-first-search,C++,Algorithm,Grid,Breadth First Search,我有一个问题,就是在给定的网格中找到最大的“加号”。 例如,如果我有以下网格: ..#.. ..#.# ##### ..#.# ..#.. 其中最大的“加号”为3号。同样,对于 ..# #.# #.# 答案是1,因为不存在特定的“加号”(当然,除了来源) 我心目中的算法是这样的: 找到一个四个方向都有#和#的位置。如图1中的(2,2) 使用广度优先搜索策略添加队列中的所有邻居以及它们所在的方向(左、右、上、下) 继续访问并添加与该特定方向相关的邻居 重复此操作,直到遇到或超出边界 在执行所有

我有一个问题,就是在给定的网格中找到最大的“加号”。 例如,如果我有以下网格:

..#..
..#.#
#####
..#.#
..#..
其中最大的“加号”为3号。同样,对于

..#
#.#
#.#
答案是1,因为不存在特定的“加号”(当然,除了来源)

我心目中的算法是这样的:

  • 找到一个四个方向都有
    #
    #
    的位置。如图1中的
    (2,2)
  • 使用广度优先搜索策略添加队列中的所有邻居以及它们所在的方向(左、右、上、下)
  • 继续访问并添加与该特定方向相关的邻居
  • 重复此操作,直到遇到
    或超出边界
  • 在执行所有这些操作时,我们可以维护一个数组,该数组可以维护每个方向上发生的
    的计数

    代码:

    int x[4] = {-1,0,1,0} ;
    int y[4] = {0,1,0,-1} ;
    int n, dir[4], result ;
    char adj[2001][2001] ;
    
    int bfs(int sx, int sy) {
        queue < pair <int, pair <int, int> > > q ;
        q.push(make_pair(0, make_pair(sx+x[0], sy+y[0]))) ;
        q.push(make_pair(1, make_pair(sx+x[1], sy+y[1]))) ;
        q.push(make_pair(2, make_pair(sx+x[2], sy+y[2]))) ;
        q.push(make_pair(3, make_pair(sx+x[3], sy+y[3]))) ;
        while (!q.empty()) {
            pair <int, pair <int, int> > curr = q.front() ;
            q.pop() ;
            int current_direction =  curr.first ;
            int current_x = curr.second.first + x[current_direction] ;
            int current_y = curr.second.second + y[current_direction] ;
            if (current_x>=0&&current_x<n&&current_y>=0&&current_y<n) {
                if (adj[current_x][current_y] == '#') {
                    ++dir[current_direction] ;
                    q.push(make_pair(current_direction, make_pair(current_x, current_y))) ;
                }
                else
                    break ;
            }
            else
                break ;
        }
        result = *min_element(dir, dir+4) ;
        return result ;
    }
    
    int main() {
        int t ; scanf("%d", &t) ;
        while (t--) {
            scanf("%d", &n) ;
            for (int i = 0; i < n; i++)
                cin >> adj[i] ;
            bool flag = true ;
            int max_plus = 0 ;
            for (int i = 1; i < n - 1; i++)
                for (int j = 1; j < n - 1; j++) {
                    if (adj[i][j] == '#' && adj[i-1][j] == '#' \\
                        && adj[i][j+1] == '#' && adj[i+1][j] == '#' \\
                        && adj[i][j-1] == '#') {
                        // cout << i << " " << j << endl ;
                        flag = false ;
                        memset(dir, 2, sizeof(dir)) ;
                        max_plus = max(max_plus, bfs(i, j)) ;
                    }
                }
            if(flag)
                cout << "1" << endl ;
            else
                cout << max_plus << endl ;
        }
        return 0 ;
    }
    
    intx[4]={-1,0,1,0};
    int y[4]={0,1,0,-1};
    int n,dir[4],result;
    char adj[2001][2001];
    内部bfs(内部sx,内部sy){
    队列q;
    q、 推送(make_对(0,make_对(sx+x[0],sy+y[0]));
    q、 推送(make_对(1,make_对(sx+x[1],sy+y[1]));
    q、 推送(make_对(2,make_对(sx+x[2],sy+y[2]));
    q、 推送(make_对(3,make_对(sx+x[3],sy+y[3]));
    而(!q.empty()){
    对电流=q.前();
    q、 pop();
    int当前_方向=当前优先;
    int current_x=curr.second.first+x[当前_方向];
    int current_y=curr.second.second+y[当前_方向];
    如果(当前值>=0&¤t\ux=0&¤t\uy>adj[i];
    布尔标志=真;
    int max_plus=0;
    对于(int i=1;i//我不知道你的代码到底出了什么问题,也不知道你的算法是否正确。但我认为你不需要BFS来解决这个问题。创建4个矩阵,保持每个
    的上下左右连续
    的数量:

    向上

    向下

    现在通过为每个元素保留至少4个矩阵来创建一个矩阵

    答案是
    min
    矩阵的最大值

    假设要计算每个“#”后面有多少个连续的“#”


    \\添加以减少SO的行数。:p解决此类问题的正确工具是调试器。在询问堆栈溢出问题之前,应逐行检查代码。有关更多帮助,请阅读。至少应[编辑]您的问题需要包含一个重现您的问题的示例,以及您在调试器中所做的观察。我认为这将具有非常高的时间和空间复杂性。矩阵的大小可以是5000 x 5000。这是
    O(n^2)
    O(n^2)
    O(n^2)
    对于5000是可以接受的。@saru95这是动态规划最简单的例子。我将把它添加到答案中。没关系,我误解了你的答案。但你的左方向图实际上又是右方向图。它不是真正的BFS,因为你没有把所有邻居都推到队列中,也没有维持访问ed list。你也在为你看到的每一个低效的
    #
    这样做。
    ..#..
    ..#.#
    #####
    ..#.#
    ..#..
    
    ..0..
    ..1.0
    00201
    ..3.2
    ..4..
    
    ..4..
    ..3.2
    00201
    ..1.0
    ..0..
    
    ..0..
    ..0.0
    43210
    ..0.0
    ..0..
    
    ..0..
    ..0.0
    01234
    ..0.0
    ..0..
    
    ..0..
    ..0.0
    00200
    ..0.0
    ..0..
    
    for i from 0 to str.length
        if s[i]=='#':
            if s[i-1]=='#': // beware of i==0
                dp[i] = dp[i-1]+1
            else 
                dp[i] = 0
    
    str ..##.###...##...
    dp  ..01.012...01...