描述
题解
深度优先搜索,这里需要强调的是,不要归置状态,只要访问过就标记为1
,另外需要设置一个tag
标签,标记上一步,防止下一步与上一步重合。当访问的下一步所访问的点已经被访问过,说明形成了环。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXMN = 55;
int n, m;
char map[MAXMN][MAXMN];
int flag[MAXMN][MAXMN]; // 标记访问状态
bool ans = false;
void solve(int x, int y, int tag)
{
if (x > n || x < 1)
{
return ;
}
else if (y > m || y < 1)
{
return ;
}
flag[x][y] = 1;
// 一号路径
if (map[x][y] == map[x + 1][y] && tag != 2)
{
if (flag[x + 1][y])
{
ans = true;
return ;
}
solve(x + 1, y, 1);
}
// 二号路径
if (map[x][y] == map[x - 1][y] && tag != 1)
{
if (flag[x - 1][y])
{
ans = true;
return ;
}
solve(x - 1, y, 2);
}
// 三号路径
if (map[x][y] == map[x][y + 1] && tag != 4)
{
if (flag[x][y + 1])
{
ans = true;
return ;
}
solve(x, y + 1, 3);
}
// 四号路径
if (map[x][y] == map[x][y - 1] && tag != 3)
{
if (flag[x][y - 1])
{
ans = true;
return ;
}
solve(x, y - 1, 4);
}
return ;
}
int main(int argc, const char * argv[])
{
while (cin >> n >> m)
{
memset(flag, 0, sizeof(flag));
for (int i = 1; i <= n; i++)
{
scanf("%s", map[i] + 1);
}
for (int i = 1; i <= n; i++)
{
if (ans)
{
break;
}
for (int j = 1; j <= m; j++)
{
if (ans)
{
break;
}
if (!flag[i][j])
{
solve(i, j, 0);
}
}
}
if (ans)
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
return 0;
}