51Nod-1416 两点 (暴力DFS)

题目链接:1416 两点 
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
 收藏
 关注

福克斯在玩一款手机解迷游戏,这个游戏叫做”两点”。基础级别的时候是在一个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 }

 

 
posted @ 2018-08-09 10:18  jealous-boy  阅读(154)  评论(0编辑  收藏  举报