[SDUT](3469)深度优先搜索练习之神奇的矩环 ---DFS(图)

来源:互联网 发布:bugclose 源码下载 编辑:程序博客网 时间:2024/06/02 03:37

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

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

学习新知:

      ①:这道题可以用暴力穷举搜索出来,复杂度O(NxM)。应该是这道题数据比较水23333

      ②:学习了一些前辈的DFS写法,感觉很棒,是个很不错的思路。

      ③:关于两种算法, 都要注意一点,就是图的边界要优化!不要越界,否则一定WA。



AC代码:

-----------------------暴力穷举-----------------------
#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;}

-----------------------DFS-----------------------
#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;}

dfs这种算法的理解:我画了两张图
                             
      其实这个算法就是从源点出发,搜索它的四个方向即上,下,左,右。若能找到与其颜色相同的点,那么他们之间就连通。然后在DFS,直到找到第四个顶点时,若能形成环,那么第四个顶点一定和源点之间有“”,这时候另标记变量flag=1,返回。我算了一下,有八种形成环的走法,每个环有四个点,那么这四个点都可以当做源点,即最终和第四个顶点连通的一定是源点。那么就是4种走法。顺时针4种,逆时针4种,即8种。
----------------------------------------------------------------------------------------------------------------

原创粉丝点击