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&¤t_x<n&¤t_y>=0&¤t_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...