(DFS入门题··找环)-CF-510B

问题:传送门

给出一个由字母组成的图,判断其中是否有相同字母组成的环(一个环最少有四个字母),有输出Yes,没有输出No。

3 4
AAAA
ABCA
AAAA
Yes

3 4
AAAA
ABCA
AADA
No

分析:

用DFS 深搜每一个字母,比如从第一个开始,A,那么就把所有与之相连接的  A  全部搜索一遍并且标记,

如果过程中遇到了一个 A 是标记过的,并且  step > 3  ,那么一定存在环,

这里有个坑。。

比如   AAAA    ,搜索到最后一个  A  时,  它会判断它前面的一个 A 是被搜过的,并且 满足  step  ,会输出 yes

但显然是  NO。。所以就需要记录一下  当前位置的上一步位置,

如果遇到被搜索过的相同字母并且不是上一步的位置并且满足step,那么就一定有环

如果最后没有找到环,那么这次搜索过的所有  A   都是不可能形成环的,,节省了很多时间。

#include <iostream>

using namespace std;

const int MAXN = 55;

char color;
char   G[MAXN][MAXN];
int book[MAXN][MAXN];
int  dir[ 4  ][ 2  ] = {-1,0,0,1,1,0,0,-1};
int m,n,flag;

bool judge(int x, int y,int nx,int ny)
{
    if(nx>=0 && nx<m && ny>=0 && ny<n && G[x][y]==G[nx][ny] && !book[nx][ny])
        return true;
    return false;
}

void DFS(int x,int y,int lx,int ly,int step)
{
    if(flag)
        return ;
    flag       = 0;
    book[x][y] = 1;

    for(int i  = 0; i < 4; i++)
    {
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        if(book[nx][ny]  && (lx!=nx || ly!=ny) && color==G[nx][ny] && step>=3)
        {
            flag = 1;                         //因为还没有进入下一步,所以这step>=3
            return ;
        }
        if(judge(x,y,nx,ny))
        {
             DFS(nx,ny,x,y,step+1);
        }
    }
    return ;
}

int main()
{
    cin >> m >> n;
    for(int i = 0; i < m; i++)
        cin >> G[i];

    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(!book[i][j])
            {
                color = G[i][j];
                DFS(i,j,0,0,0);
            }
            if(flag)
                break;
        }
        if(flag)
            break;
    }
    if(flag)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41003528/article/details/81428672