给出一个矩阵,判断矩阵内的字母能否成环
INPUT:
第一行2个整数n,m(n,m<50) 表示矩阵的行列
下面n行 给出字母矩阵
OUTPUT:
有环输出Yes,否则输出No
案例输入1:
3 4
AAAA
ABCA
AAAA案例输出1:
Yes
案例输入2:
3 4
AAAA
ABCA
AADA案例输出2:
No
案例输入3:
4 4
YYYR
BYBY
BBBY
BBBY案例输出3:
Yes (4/6个B字母能成一个环)
基本思想:
遍历每个字母, 沿着字母走,走过的标记一下,如走到标记过的字母,则表示能成环;
易错:回头的处理, 走的下一步 一定不能是上一步的位置
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int MAX=52;
char a[MAX][MAX];
int vis[MAX][MAX]; //用作标记的二维数组
int n,m;
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
bool dfs(int x,int y,int fx,int fy) //为了防止回头 fx,fy表示上一步的位置
{
if(vis[x][y]) //如果被走过,表示已成环
return true;
else
vis[x][y] = 1; //未走过,标记为走过
for(int i=0;i<4;i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
if( nx == fx && ny == fy)
continue; // 是否是上一步
if( nx <=0 || nx>n || ny<=0 || ny>m)
continue; //是否越界
if(a[nx][ny] == a[x][y]) //是否是一样的字母 只能走相同的字母
if(dfs(nx,ny,x,y))
return true;
}
return false;
}
int main()
{
bool flag;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(!vis [i][j])
{
if(dfs(i,j,i,j))
{
flag = true;
}
}
}
if(flag)
break;
}
cout<<(flag?"Yes":"No")<<endl;
}