CF510B Fox And Two Dots
题目大意
矩阵中各个方格都有颜色,判断是否有相同颜色的方块可以组成环。(原题链接:CF510B Fox And Two Dots)
输入:
第一行:\(n\), \(m\),表示矩阵的行和列
接下来\(n\)行: 输入矩阵
输出:
如果有环则输出:\(Yes\), 否则输出:\(No\);
样例:
输入样例:\(*1\)
3 4
AAAA
ABCA
AAAA
输出样例: \(*1\)
Yes
输入样例:\(*2\)
3 4
AAAA
ABCA
AADA
输出样例: \(*2\)
No
思路:
其实就是判断连通块,然后再加个条件能否搜到初始点。
不过要注意的是:
1.不能搜当前点的上一个状态,即用两个变量记录一下即可,如果是就\(continue\)即可
剩下的就是常规\(dfs\)了,还有就是可以提前记录一下每个字母的数量,如果小于\(4\)那么可以直接不用搜了。
代码:
#include <iostream>
using namespace std;
const int N = 55;
int n, m;
char g[N][N];
bool st[N][N], flag;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int cnt[27];
void dfs(int x, int y, char temp, int lastX, int lastY)
{
st[x][y] = true;
for(int i = 0; i < 4; i++)
{
int xx = x + dx[i], yy = y + dy[i];
if(xx == lastX && yy == lastY) continue; //上个点
if(st[xx][yy] && g[xx][yy] == temp) flag = 1; //说明搜到
if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && g[xx][yy] == temp && !st[xx][yy]) dfs(xx, yy, temp, x, y);
}
return;
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
cin >> g[i][j];
cnt[g[i][j] - 'A']++;
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
if(!st[i][j] && cnt[g[i][j] - 'A'] >= 4) dfs(i, j, g[i][j], 0, 0);
if(flag == 1)
{
cout << "Yes" << endl;
return 0;
}
}
}
if(!flag) cout << "No" << endl;
return 0;
}