思路:我用的bfs,从一个未被访问的点开始bfs,走同一种颜色的格子,同时不能走回头路,如果存在两条路最后能碰头并且长度之和大于4就输出Yes,否则No。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 55
using namespace std;
struct Node
{
int x,y,step,d;
};
int dir[4][2]={-1,0,0,1,1,0,0,-1};
char mp[maxn][maxn];
int step[maxn][maxn];
bool vis[maxn][maxn];
int n,m;
bool isok(int x,int y)
{
if (x>=0&&x<n&&y>=0&&y<m)
return true;
return false;
}
bool bfs(int x,int y)
{
Node st,now;
queue<Node>Q;
while (!Q.empty())
Q.pop();
st.x=x;st.y=y;st.step=0;st.d=-1;
Q.push(st);
step[x][y]=0;
vis[x][y]=true;
while (!Q.empty())
{
st=Q.front(); Q.pop();
for (int i=0;i<4;i++)
{
if (st.d==(i+2)%4) continue; //不能走回头路
now.x=st.x+dir[i][0];
now.y=st.y+dir[i][1];
now.step=st.step+1;
now.d=i; //记录当前点走到下一个点是从哪个方向过去的
if (isok(now.x,now.y)&&mp[st.x][st.y]==mp[now.x][now.y])
{
if (vis[now.x][now.y]&&(now.step+step[now.x][now.y]+1)>=4) //碰头了并且长度之和大于4
return true;
if (!vis[now.x][now.y]) //没有被访问过就入队列
{
vis[now.x][now.y]=true;
step[now.x][now.y]=now.step;
Q.push(now);
}
}
}
}
return false;
}
bool solve()
{
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
if (!vis[i][j]&&bfs(i,j))
return true;
return false;
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
for (int i=0;i<n;i++)
scanf("%s",mp[i]);
memset(vis,false,sizeof(vis));
memset(step,0,sizeof(step));
if (solve()) printf("Yes\n");
else printf("No\n");
}
return 0;
}