深度优先搜索练习之神奇的矩环
Time Limit: 1000 ms Memory Limit: 65536 KiB
Submit Statistic
Problem Description
小鑫的女朋友被魔王抢走了!
魔王留给小鑫一张n*m大的表,上面有各种各样的颜色,用A-Z这26个字母来表示。魔王留给他一个任务,如果小鑫可以在这张表中找出任意一个长度大于1的环,并且这个环的颜色是相同的,魔王就把小鑫的女朋友还给他。为了从魔王手中夺回他的女朋友,小鑫请你帮忙,你能帮帮他吗?
Input
多组输入。
每组的第一行有两个整数n,m。代表表的大小。
接下来是由A-Z的一些字母所构成的n行m列的表。
1<=n,m<=200
Output
如果可以救回他的女朋友,输出Yes,否则输出No
Sample Input
4 7 ABCBBAA BCBCBCB AABBCCA ACCCBBB 10 3 AAC ABB BBA AAC CBC CCA CBB CCA CCB BAA
Sample Output
No Yes
Hint
Source
这个题参考学长思路 写下存档:https://blog.csdn.net/m0_37624640/article/details/77102310
dfs这种算法的理解:学长画了两张图
其实这个算法就是从源点出发,搜索它的四个方向即上,下,左,右。若能找到与其颜色相同的点,那么他们之间就连通。然后在DFS,直到找到第四个顶点时,若能形成环,那么第四个顶点一定和源点之间有“边”,这时候另标记变量flag=1,返回。我算了一下,有八种形成环的走法,每个环有四个点,那么这四个点都可以当做源点,即最终和第四个顶点连通的一定是源点。那么就是4种走法。顺时针4种,逆时针4种,即8种。
----------------------------------------------------------------------------------------------------------------
/*模仿别人代码*/
#include <bits/stdc++.h>
using namespace std;
char gra[222][222];
int cat[222][222];
int n, m, flag;
void dfs(int x, int y, int i, int j)
{cat[x][y] = 1;if (flag)return;if (x - 1 >= 0 && gra[x - 1][y] == gra[x][y]){if (cat[x - 1][y] && ((x - 1 != i) || (y != j)))flag = 1;else if (!cat[x - 1][y])dfs(x - 1, y, x, y);}if (x + 1 < n && gra[x + 1][y] == gra[x][y]){if (cat[x + 1][y] && ((x + 1 != i) || (y != j)))flag = 1;else if (!cat[x + 1][y])dfs(x + 1, y, x, y);}if (y - 1 >= 0 && gra[x][y - 1] == gra[x][y]){if (cat[x][y - 1] && ((x != i) || (y - 1 != j)))flag = 1;else if (!cat[x][y - 1])dfs(x, y - 1, x, y);}if (y + 1 < m && gra[x][y + 1] == gra[x][y]){if (cat[x][y + 1] && ((x != i) || (y + 1 != j)))flag = 1;else if (!cat[x][y + 1])dfs(x, y + 1, x, y);}
}
int main()
{ios::sync_with_stdio(false);while (cin >> n >> m){memset(cat, 0, sizeof(cat));flag = 0;for (int i = 0; i < n; i++){for (int j = 0; j < m; j++)cin >> gra[i][j];}for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){if (!cat[i][j])dfs(i, j, i, j);if (flag)break;}if (flag)break;}if (flag)cout << "Yes" << endl;elsecout << "No" << endl;}return 0;
}