问题:传送门
给出一个由字母组成的图,判断其中是否有相同字母组成的环(一个环最少有四个字母),有输出Yes,没有输出No。
3 4 AAAA ABCA AAAA Yes 3 4 AAAA ABCA AADA No
分析:
用DFS 深搜每一个字母,比如从第一个开始,A,那么就把所有与之相连接的 A 全部搜索一遍并且标记,
如果过程中遇到了一个 A 是标记过的,并且 step > 3 ,那么一定存在环,
这里有个坑。。
比如 AAAA ,搜索到最后一个 A 时, 它会判断它前面的一个 A 是被搜过的,并且 满足 step ,会输出 yes
但显然是 NO。。所以就需要记录一下 当前位置的上一步位置,
如果遇到被搜索过的相同字母并且不是上一步的位置并且满足step,那么就一定有环。
如果最后没有找到环,那么这次搜索过的所有 A 都是不可能形成环的,,节省了很多时间。
#include <iostream>
using namespace std;
const int MAXN = 55;
char color;
char G[MAXN][MAXN];
int book[MAXN][MAXN];
int dir[ 4 ][ 2 ] = {-1,0,0,1,1,0,0,-1};
int m,n,flag;
bool judge(int x, int y,int nx,int ny)
{
if(nx>=0 && nx<m && ny>=0 && ny<n && G[x][y]==G[nx][ny] && !book[nx][ny])
return true;
return false;
}
void DFS(int x,int y,int lx,int ly,int step)
{
if(flag)
return ;
flag = 0;
book[x][y] = 1;
for(int i = 0; i < 4; i++)
{
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(book[nx][ny] && (lx!=nx || ly!=ny) && color==G[nx][ny] && step>=3)
{
flag = 1; //因为还没有进入下一步,所以这step>=3
return ;
}
if(judge(x,y,nx,ny))
{
DFS(nx,ny,x,y,step+1);
}
}
return ;
}
int main()
{
cin >> m >> n;
for(int i = 0; i < m; i++)
cin >> G[i];
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
if(!book[i][j])
{
color = G[i][j];
DFS(i,j,0,0,0);
}
if(flag)
break;
}
if(flag)
break;
}
if(flag)
cout << "Yes" << endl;
else
cout << "No" << endl;
return 0;
}