小鑫的女朋友被魔王抢走了!
魔王留给小鑫一张n*m大的表,上面有各种各样的颜色,用A-Z这26个字母来表示。魔王留给他一个任务,如果小鑫可以在这张表中找出任意一个长度大于1的环,并且这个环的颜色是相同的,魔王就把小鑫的女朋友还给他。为了从魔王手中夺回他的女朋友,小鑫请你帮忙,你能帮帮他吗?
魔王留给小鑫一张n*m大的表,上面有各种各样的颜色,用A-Z这26个字母来表示。魔王留给他一个任务,如果小鑫可以在这张表中找出任意一个长度大于1的环,并且这个环的颜色是相同的,魔王就把小鑫的女朋友还给他。为了从魔王手中夺回他的女朋友,小鑫请你帮忙,你能帮帮他吗?
Input
多组输入。
每组的第一行有两个整数n,m。代表表的大小。
接下来是由A-Z的一些字母所构成的n行m列的表。
1<=n,m<=200
每组的第一行有两个整数n,m。代表表的大小。
接下来是由A-Z的一些字母所构成的n行m列的表。
1<=n,m<=200
Output
如果可以救回他的女朋友,输出Yes,否则输出No
Example Input
4 7 ABCBBAA BCBCBCB AABBCCA ACCCBBB 10 3 AAC ABB BBA AAC CBC CCA CBB CCA CCB BAA
Example Output
No
Yes
三个小时折腾出这一道题。。。题意很明确,就是判断图中是否有环,如果当前点已被访问,它的下一个节点也被访问且不是当前点的父节点,那么就是有环,由于图中字母不一样,所以挨个遍历每个字母相同的连通块看是否有环
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 210;
int n, m;
char map[N][N];
bool vis[N][N];
bool flag;
int xx[4] = {1, 0, 0, -1};
int yy[4] = {0, 1, -1, 0};
void DFS(int x, int y, int xp, int yp) //x,y为当前点的坐标,xp,yp为父节点
{
vis[x][y] = 1;
for(int k = 0; k < 4; k++)
{
int i = x + xx[k];
int j = y + yy[k];
if(i >= 0 && i < n && j >= 0 && j < m && map[i][j] == map[x][y])
{
if(!vis[i][j])
DFS(i, j, x, y);
else if(i != xp && j != yp) //当前点的下一点不是父节点且已经被访问,说明有环
{
flag = true;
return;
}
}
}
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++)
scanf("%s", map[i]);
flag = false;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(!vis[i][j])
{
DFS(i, j, i, j); //访问每个连通块
if(flag)
break;
}
}
if(flag)
break;
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}