题目链接,有时可能会崩
输出
输入样例 1
3 4
AAAA
ABCA
AAAA
输出样例 1
Yes
思路分析,其实就是dfs的一个应用,对于判断是否成环只要判这个点是否已经被标记且,这个点所对应的步数跟上一步所对应的步数差值大于3。
在这里我是先把相同颜色的点都用vector+pair来储存,这样方便查找,原因是在a颜色的第一个储存位置开始深搜时,势必会标记其他相同颜色的点,这样如果从这一个点开始搜索都不能搜到环,那么那些在搜索过程中被标记的点也不会搜到,也算是一种剪枝吧。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int maxn = 55;
vector<pii>vec[27];
int vis[maxn][maxn];
char mapp[maxn][maxn];
int step[maxn][maxn];
int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
int flag = 0;
int n, m;
bool check(int x, int y)
{
if (x >= 1 && x <= n && y >= 1 && y <= m)
return true;
else
return false;
}
void dfs(int x, int y)
{
vis[x][y] = 1;
for (int i = 0; i < 4; i++)
{
int fx, fy;
fx = x + dir[i][0];
fy = y + dir[i][1];
if (check(fx, fy) == true &&(mapp[fx][fy]==mapp[x][y]))
{
if (vis[fx][fy] == 1)
{
if (step[x][y] - step[fx][fy] >= 3)
{
flag = 1;
return;
}
else continue;
}
else if (vis[fx][fy] == 0)
{
step[fx][fy] = step[x][y] + 1;
dfs(fx, fy);
if (flag == 1) return;
}
}
}
}
void ini()
{
flag = 0;
memset(vis, 0, sizeof(vis));
memset(step, 0, sizeof(step));
for (int i = 1; i <= 26; i++)
vec[i].clear();
}
int main()
{
while (scanf("%d %d", &n, &m) != EOF)
{
ini();
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> mapp[i][j];
int t = mapp[i][j] - 64;
vec[t].push_back(make_pair(i, j));
}
}
for (int i = 1; i <= 26; i++)
{
if (vec[i].size() == 0)continue;
for (int j = 0; j < vec[i].size(); j++)
{
pii p = vec[i][j];
if (vis[p.first][p.second] == 1) continue;
dfs(p.first, p.second);
if (flag == 1) break;
}
if (flag == 1) break;
}
if (flag == 1) printf("Yes\n");
else if (flag == 0) printf("No\n");
}
return 0;
}