51nod 1416 兩點 【dfs+特殊判斷】

題目來源: 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章