51Nod-1416 两点 (暴力DFS)
收藏
关注
福克斯在玩一款手机解迷游戏,这个游戏叫做”两点”。基础级别的时候是在一个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 是相邻的当且仅当他们有公共边。
当给出一幅格点时,请确定里面是否有环。
Input
单组测试数据。 第一行包含两个整数n和m (2≤n,m≤50):板子的行和列。 接下来n行,每行包含一个有m个字母的串,表示当前行每一个点的颜色。每一个字母都是大写字母。
Output
如果有环输出Yes,否则输出No。
Input示例
3 4 AAAA ABCA AAAA 3 4 AAAA ABCA AADA
Output示例
Yes No
参考博客链接:https://blog.csdn.net/woyuhuaijin/article/details/51493922
题意:给一个n*m的单元,单元上同样的大写字母表示相同的颜色,不同的大写字母表示不同的颜色,问你在图中是否存在一个环(这个环是由某个颜色形成的).
思路:暴力DFS,visit[i][j]标记走过的点(第几步到这里),用step记录现在DFS走到的位置是第几步,如果走到走过的位置则用step-visit[i][j]看两者的差值。
如果差值>=3则表明形成了环。则可以直接退出输出Yes.
visit[i][j]有两个状态: 0:表示该点未走过 >0:表示第一次走到该点时的步数。
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 using namespace std; 5 char s[55][55]; 6 int visit[55][55]; 7 int dir[4][2]={1,0,-1,0,0,1,0,-1};//direction 8 int flag=0;//标记是否有环 9 int n,m; 10 void DFS(int x,int y,int step) 11 { 12 for(int i=0;i<4;i++) 13 { 14 int xx=x+dir[i][0]; 15 int yy=y+dir[i][1]; 16 if(xx>=0&&xx<n&&yy>=0&&yy<m&&s[xx][yy]==s[x][y])//在范围内切是相同"颜色"(字母) 17 { 18 if(visit[xx][yy]>0)//如果走到走过的地方 19 { 20 if(step-visit[xx][yy]>=3)//判断是否形成环 21 { 22 flag=1;return;//形成环,返回 23 } 24 } 25 else if(visit[xx][yy]==0)//未走过的地方 26 { 27 visit[xx][yy]=step+1;//走过去step+1 28 DFS(xx,yy,step+1); 29 } 30 if(flag==1) return; 31 } 32 } 33 } 34 int main() 35 { 36 scanf("%d%d",&n,&m); 37 getchar(); 38 memset(visit,0,sizeof(visit)); 39 for(int i=0;i<n;i++) 40 scanf("%s",s[i]); 41 for(int i=0;i<n;i++) 42 { 43 for(int j=0;j<m;j++) 44 { 45 if(visit[i][j]==0) 46 { 47 visit[i][j]=1;//初始地方为1 48 DFS(i,j,1); 49 if(flag==1) break;//发现有环break 50 } 51 if(flag==1) break;//发现有环break 52 } 53 if(flag==1) break;//发现有环break 54 } 55 if(flag==1) printf("Yes\n"); 56 else printf("No\n"); 57 return 0; 58 }