SDUT-3469 深度优先搜索练习之神奇的矩环(暴力/DFS)

来源:互联网 发布:python数据挖掘工具包 编辑:程序博客网 时间:2024/06/05 18:36

深度优先搜索练习之神奇的矩环

Time Limit: 1000MS Memory Limit: 65536KB
Submit Statistic Discuss

Problem Description

小鑫的女朋友被魔王抢走了!
魔王留给小鑫一张n*m大的表,上面有各种各样的颜色,用A-Z这26个字母来表示。魔王留给他一个任务,如果小鑫可以在这张表中找出任意一个长度大于1的环,并且这个环的颜色是相同的,魔王就把小鑫的女朋友还给他。为了从魔王手中夺回他的女朋友,小鑫请你帮忙,你能帮帮他吗?

Input

多组输入。
每组的第一行有两个整数n,m。代表表的大小。
接下来是由A-Z的一些字母所构成的n行m列的表。
1<=n,m<=200

Output

如果可以救回他的女朋友,输出Yes,否则输出No

Example Input

4 7ABCBBAABCBCBCBAABBCCAACCCBBB10 3AACABBBBAAACCBCCCACBBCCACCBBAA

Example Output

NoYes

Hint


Author

1.DFS 参考
2.暴力 参考
//DFS1
#include <bits/stdc++.h>using namespace std;char c[202][202];int flag,v[202][202],n,m;int dx[4]= {0,1,0,-1};int dy[4]= {1,0,-1,0};void DFS(int x,int y,int xx,int yy)//x,y表示当前点的坐标  xx,yy表示判断是否构成环的“环”上的第一个点的坐标{    v[x][y]=1;    for(int i=0; i<4; i++)    {        int a=x+dx[i];        int b=y+dy[i];        if(c[a][b]==c[xx][yy]&&a>=0&&a<n&&b>=0&&b<m)        {            if(!v[a][b])                DFS(a,b,x,y);            else if(!(a==xx&&b==yy)) //当前点的下一点的坐标不和初始点的坐标完全重合且此点已经被访问,说明有环            {                flag=1;                return;            }        }    }}int main(){    int i,j;    while(cin>>n>>m)    {        memset(v,0,sizeof(v));        flag=0;        for(i=0; i<n; i++)           cin>>c[i];        for(i=0; i<n; i++)        {            for(j=0; j<m; j++)            {                if(!v[i][j])                {                    DFS(i,j,i,j);//访问每个点                    if(flag)                        break;//剪枝                }            }            if(flag)                break;//剪枝        }        if(flag)            cout<<"Yes\n";        else            cout<<"No\n";    }    return 0;}
//DFS2
#include<iostream>#include<cstring>using namespace std;char mmap[205][205];int vis[205][205];int n,m;int flag;void dfs(int x,int y,int px,int py){    vis[x][y]=1;    if(flag)        return;    if(x-1>=0 && mmap[x-1][y]==mmap[x][y])    {        if(vis[x-1][y] && ((x-1!=px)||(y!=py)))            flag=1;        else if(!vis[x-1][y])            dfs(x-1,y,x,y);    }    if(x+1<n && mmap[x+1][y]==mmap[x][y])    {        if(vis[x+1][y] && ((x+1!=px) || (y!=py)))            flag=1;        else if(!vis[x+1][y])            dfs(x+1,y,x,y);    }    if(y-1>=0 && mmap[x][y-1]==mmap[x][y])    {        if(vis[x][y-1] && ((x!=px)||(y-1!=py)))            flag=1;        else if(!vis[x][y-1])            dfs(x,y-1,x,y);    }    if(y+1<m && mmap[x][y+1]==mmap[x][y])    {        if(vis[x][y+1] && ((x!=px)||(y+1!=py)))            flag=1;        else if(!vis[x][y+1])            dfs(x,y+1,x,y);    }}int main(){    while(cin>>n>>m)    {        int i,j;        flag=0;        memset(mmap,0,sizeof(mmap));        memset(vis,0,sizeof(vis));        for(i=0;i<n;i++)            cin>>mmap[i];        for(i=0;i<n;i++)        {            for(j=0;j<m;j++)            {                if(!vis[i][j])                    dfs(i,j,i,j);                if(flag)//剪枝优化                    break;            }            if(flag)//剪枝优化                break;        }        if(flag)            cout<<"Yes"<<endl;        else            cout<<"No"<<endl;    }    return 0;}


暴力:只需判读有没有一个边长为1的正方形环即可
#include<iostream>#include<cstring>using namespace std;int main(){    int n,m;    char mmap[205][205];    while(cin>>n>>m)    {        int k;        int flag=0;        int i;        int j;        for(i=0;i<n;i++)            cin>>mmap[i];        for(i=0;i<n-1;i++) //i<n-1 防止越界        {            for(j=0;j<m-1;j++) //j<m-1 防止越界            {                if(mmap[i][j]==mmap[i][j+1])                {                    if(mmap[i][j]==mmap[i+1][j])                    {                        if(mmap[i][j]==mmap[i+1][j+1])                        {                            flag=1;                            break;                        }                    }                }            }            if(flag)//剪枝优化                break;        }        if(flag)            cout<<"Yes"<<endl;        else            cout<<"No"<<endl;    }    return 0;}