AC截图
思路:
在图中找到一个环即可,枚举每个点,以该点分别为起点和终点进行dfs,如果相遇且步数大于4,则成功找到
简洁代码
用vis 标记状态 注意开始的点标为3 起点开始搜的标为1 终点开始搜的标为2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n, m;
char A[55][55];
int vis[55][55];
int arr[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
int dfs(int cur, int sx, int sy,int ex,int ey, char symbol) {
int i, j;
for (i = 0; i < 4; i++) { //从起点开始搜
int xx = sx + arr[i][0];
int yy = sy + arr[i][1];
if (xx >= 0 && xx < n&&yy >= 0 && yy < m&&A[xx][yy] == symbol) {
if (vis[xx][yy]) { //如果是终点开始搜过的
if (vis[xx][yy]==2&&cur + 1 >= 4)return 1;
}
else {
vis[xx][yy] = 1;
for (j = 0; j < 4; j++) { //从终点开始搜
int xxx = ex + arr[j][0];
int yyy = ey + arr[j][1];
if (xxx >= 0 && xxx < n&&yyy >= 0 && yyy < m&&A[xxx][yyy] == symbol) {
if (vis[xxx][yyy]) { //如果是起点开始搜过的
if (vis[xxx][yyy]==1&&cur + 2 >= 4)return 1;
}
else {
vis[xxx][yyy] = 2;
int flg = dfs(cur + 2, xx, yy, xxx, yyy, symbol);
if (flg)return flg;
vis[xxx][yyy] = 0; //注意还原状态
}
}
}
vis[xx][yy] = 0; //注意还原状态
}
}
}
return 0;
}
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
while (scanf("%d%d", &n, &m) != EOF && (n || m)) {
int i, j, k;
memset(A, 0, sizeof(A));
memset(vis, 0, sizeof(vis));
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
char ch = getchar();
while (ch == '\n' || ch == ' ')ch = getchar();
A[i][j] = ch;
}
}
int flg = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
vis[i][j] = 3;
flg = dfs(1, i, j, i, j, A[i][j]);
if (flg)break;
vis[i][j] = 0;
}
if (flg)break;
}
if (flg)printf("Yes\n");
else printf("No\n");
}
return 0;
}