题目来源: 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
/*
由于dfs 用的不是很熟练
就这道51nod 里的dfs 来说 一开始对了一半 后来改了对了一些 又改了 又对了一些 最后对了90%
看了别人的博客 发现这么简单就实现了 心酸 关键是不会用
通过下载的数据 发现几个问题 1.标记点的回溯 2.开始与结束的标志 我用了一个循环去开始搜索
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
char map[55][55]; //存图形
int vis[55][55]; //是否出现过
int t,u; //当前的位置 起始点 or 终止点
int flag; //用于判断是否联通
int n,m;//矩阵大小
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int i;
void dfs(int x,int y){
//cout<<x<<" "<<y<<endl;
for(i=0;i<4;i++){
int nx=x+dir[i][0],ny=y+dir[i][1];
if(nx==t&&ny==u&&map[nx][ny]==map[x][y]&&vis[x][y]!=2){ flag=1; return ;}
if(!vis[nx][ny]&&nx>=0&&nx<n&&ny>=0&&ny<m&&map[x][y]==map[nx][ny]){ vis[nx][ny]=1; dfs(nx,ny);vis[nx][ny]=0;}
}
}
int main(){
while(cin>>n>>m){
memset(vis,0,sizeof(vis));
memset(map,' ',sizeof(map));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>map[i][j];
flag=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!vis[i][j]){
t=i,u=j;
vis[i][j]=1;
for(int k=0;k<4;k++)
if(map[i+dir[k][0]][j+dir[k][1]]==map[i][j]){ vis[i+dir[k][0]][j+dir[k][1]]=2; dfs(i+dir[k][0],j+dir[k][1]);vis[i+dir[k][0]][j+dir[k][1]]=0;break;}
vis[i][j]=0;
}
if(flag){ cout<<"Yes"<<endl;break;}
}
if(flag) break;
}
if(!flag) cout<<"No"<<endl;
}
return 0;
}
/*
3 4
AAAA
ABCA
AAAA
3 4
AAAA
ABCA
AADA
*/
#include<iostream>
#include<string.h>
#include<string>
using namespace std;int n,m;
char map[55][55];
int vis[55][55];
int flag=1;
void dfs(char z,int x,int y,int v){
if(!flag) return ;
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++){
if(i==j||i!=0&&j!=0||i+x>=n||i+x<0||j+y>=m||j+y<0) continue;
if(vis[x+i][y+j]==-1&&v>2) {flag=0;return ;}
if(!vis[x+i][y+j]&&z==map[x+i][y+j]){
vis[x+i][y+j]=1;
dfs(z,x+i,y+j,v+1);//v 所过的路径长度
vis[x+i][y+j]=0;
}
}
}
int main(){
cin>>n>>m;
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++) cin>>map[i];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
vis[i][j]=-1;
dfs(map[i][j],i,j,1);
vis[i][j]=0;
}
if(!flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}