福克斯在玩一款手机解迷游戏,这个游戏叫做”两点”。基础级别的时候是在一个n×m单元上玩的。像这样:
每一个单元有包含一个有色点。我们将用不同的大写字母来表示不同的颜色。
这个游戏的关键是要找出一个包含同一颜色的环。看上图中4个蓝点,形成了一个环。一般的,我们将一个序列 d1,d2,...,dk 看成一个环,当且仅当它符合下列条件时:
1. 这k个点不一样,即当 i≠j时, di 和 dj不同。
2. k至少是4。
3. 所有的点是同一种颜色。
4. 对于所有的 1≤i≤k-1: di 和 di+1 是相邻的。还有 dk 和 d1 也应该相邻。单元 x 和单元 y 是相邻的当且仅当他们有公共边。
当给出一幅格点时,请确定里面是否有环。
第一行包含两个整数n和m (2≤n,m≤50):板子的行和列。
接下来n行,每行包含一个有m个字母的串,表示当前行每一个点的颜色。每一个字母都是大写字母。
3 4 AAAA ABCA AAAA 3 4#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; char mp[52][52]; int book[52][52]; int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; int n,m,flag,t1,t2; void dfs(int x,int y,int s) { if(flag==1)return; for(int i=0;i<4;i++) { int tx=x+next[i][0]; int ty=y+next[i][1]; if(tx<0||ty<0||tx>=n||ty>=m||mp[tx][ty]!=mp[x][y])continue; if(s>=3&&tx==t1&&ty==t2) { flag=1; return; } if(book[tx][ty]==0) { book[tx][ty]=1; //printf("%d %d %d %c--\n",tx,ty,s+1,mp[tx][ty]); dfs(tx,ty,s+1); book[tx][ty]=0; } } return; } int main() { while(~scanf("%d%d",&n,&m)) { for(int i=0;i<n;i++) scanf("%s",mp[i]); memset(book,0,sizeof(book)); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { book[i][j]=1; t1=i; t2=j; flag=0; dfs(i,j,0); if(flag==1)break; } if(flag==1)break; } if(flag==1) printf("Yes\n"); else printf("No\n"); } }
AAAAABCAAADA
YesNo
这道题目就是说从一点出发看能否形成一个圈,开始的时候想的是广搜,后来在写的过程中发现自己的想法有错误,然后就换成深搜,在写深搜的时候也出现了一个问题,就是在找出发点的时候,本来想的是只要发现一个点走过了并且和出发点的字母相同且走的步数必须要大于三,这样就可以判定了,后来想了想还是有错,看了一下别人的方法发现只要把初始点坐标保存一下,只要走回到初始点就说明有圈。