題目來源: 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;
}