CF Fox And Two Dots (DFS)

Fox And Two Dots
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Fox Ciel is playing a mobile puzzle game called "Two Dots". The basic levels are played on a board of size n × m cells, like this:

CF Fox And Two Dots (DFS)

Each cell contains a dot that has some color. We will use different uppercase Latin characters to express different colors.

The key of this game is to find a cycle that contain dots of same color. Consider 4 blue dots on the picture forming a circle as an example. Formally, we call a sequence of dots d1, d2, ..., dk a cycle if and only if it meets the following condition:

  1. These k dots are different: if i ≠ j then di is different from dj.
  2. k is at least 4.
  3. All dots belong to the same color.
  4. For all 1 ≤ i ≤ k - 1: di and di + 1 are adjacent. Also, dk and d1 should also be adjacent. Cells x and y are called adjacent if they share an edge.

Determine if there exists a cycle on the field.

Input

The first line contains two integers n and m (2 ≤ n, m ≤ 50): the number of rows and columns of the board.

Then n lines follow, each line contains a string consisting of m characters, expressing colors of dots in each line. Each character is an uppercase Latin letter.

Output

Output "Yes" if there exists a cycle, and "No" otherwise.

Sample test(s)
input
3 4
AAAA
ABCA
AAAA
output
Yes
input
3 4
AAAA
ABCA
AADA
output
No
input
4 4
YYYR
BYBY
BBBY
BBBY
output
Yes
input
7 6
AAAAAB
ABBBAB
ABAAAB
ABABBB
ABAAAB
ABBBAB
AAAAAB
output
Yes
input
2 13
ABCDEFGHIJKLM
NOPQRSTUVWXYZ
output
No




读错题了,一直以为是要找矩形,比赛快结束才被队友提醒。
DFS一下就可以,每个点记录一下它是从起点出发的第几个点,如果搜索的过程中遇到了走过的点,那么判断一下这两个点的差是否大于等于3,如果满足就说明形成了一个环。本来想的是,如果从某个点出发没找到,那么就说明和这个点连通的所有点都不可行,于是加入了一个剪枝,将这一连通分量减掉,但是似乎没什么作用,加和不加都是15ms,网上还有一种更炫的写法,就是把起点放在当前点的屁股后面,如果遇到了走过的点就找到,我有空试试,写出来的话就更新上来。

---------------------------------------------------------------------------------------------------------

深夜补发,刚才说的那个算法写了下,实际效果没想象的那么好,还没有我之前写的那个快,不过仔细想想,复杂度貌似是一样的。




不加剪枝:
#include <bits/stdc++.h>

using    namespace    std;



const    int    UPDATE[][2] = {{0,1},{0,-1},{1,0},{-1,0}};

char    MAP[55][55];

int    N,M;

struct    Node

{

    bool    vis = 0;

    int    n = 0;

}VIS[55][55];



bool    dfs(int,int,int,char);

int    main(void)

{

    cin >> N >> M;



    for(int i = 1;i <= N;i ++)

        cin >> MAP[i] + 1;

    for(int i = 1;i <= N;i ++)

        for(int j = 1;j <= M;j ++)

        {

            VIS[i][j].vis = VIS[i][j].n = 1;

            if(dfs(i,j,1,MAP[i][j]))

            {

                puts("Yes");

                return    0;

            }

            VIS[i][j].vis = VIS[i][j].n = 0;

        }

    puts("No");



    return    0;

}



bool    dfs(int x,int y,int sum,char color)

{

    for(int i = 0;i < 4;i ++)

    {

        int    new_x = x + UPDATE[i][0];

        int    new_y = y + UPDATE[i][1];

        if(new_x > N || new_x < 1 || new_y > M || new_y < 1 || 

           MAP[new_x][new_y] != color)

            continue;



        if(VIS[new_x][new_y].vis && sum - VIS[new_x][new_y].n + 1 >= 4)

            return    true;

        if(VIS[new_x][new_y].vis)

            continue;



        VIS[new_x][new_y].vis = true;

        VIS[new_x][new_y].n = sum + 1;

        if(dfs(new_x,new_y,sum + 1,color))

            return    true;

        VIS[new_x][new_y].vis = false;

        VIS[new_x][new_y].n = sum;

    }



    return    false;

}

 

 

加了剪枝:

#include <bits/stdc++.h>

using    namespace    std;



const    int    UPDATE[][2] = {{0,1},{0,-1},{1,0},{-1,0}};

char    MAP[55][55];

int    N,M;

struct    Node

{

    bool    vis = 0;

    int    n = 0;

}VIS[55][55];



bool    dfs(int,int,int,char);

void    cut(int,int,char);

int    main(void)

{

    cin >> N >> M;



    for(int i = 1;i <= N;i ++)

        cin >> MAP[i] + 1;

    for(int i = 1;i <= N;i ++)

        for(int j = 1;j <= M;j ++)

        {

            if(MAP[i][j] == '.')

                continue;

            VIS[i][j].vis = VIS[i][j].n = 1;

            if(dfs(i,j,1,MAP[i][j]))

            {

                puts("Yes");

                return    0;

            }

            VIS[i][j].vis = VIS[i][j].n = 0;

            cut(i,j,MAP[i][j]);

        }

    puts("No");



    return    0;

}



bool    dfs(int x,int y,int sum,char color)

{

    for(int i = 0;i < 4;i ++)

    {

        int    new_x = x + UPDATE[i][0];

        int    new_y = y + UPDATE[i][1];

        if(new_x > N || new_x < 1 || new_y > M || new_y < 1 || 

           MAP[new_x][new_y] != color)

            continue;



        if(VIS[new_x][new_y].vis && sum - VIS[new_x][new_y].n + 1 >= 4)

            return    true;

        if(VIS[new_x][new_y].vis)

            continue;



        VIS[new_x][new_y].vis = true;

        VIS[new_x][new_y].n = sum + 1;

        if(dfs(new_x,new_y,sum + 1,color))

            return    true;

        VIS[new_x][new_y].vis = false;

        VIS[new_x][new_y].n = sum;

    }



    return    false;

}



void    cut(int x,int y,char cor)

{

    for(int i = 0;i < 4;i ++)

    {

        int    new_x = x + UPDATE[i][0];

        int    new_y = y + UPDATE[i][1];

        if(new_x > N || new_x < 1 || new_y > M || new_y < 1 || 

           MAP[new_x][new_y] != cor || VIS[new_x][new_y].vis)

            continue;

        MAP[new_x][new_y] = '.';

        cut(new_x,new_y,cor);

    }

}

 

 

网上的算法:

#include <bits/stdc++.h>

using    namespace    std;



const    int    UPDATE[][2] = {{0,1},{0,-1},{1,0},{-1,0}};

int    N,M;

char    MAP[55][55];

bool    VIS[55][55];

int    BACK_X,BACK_Y;



bool    dfs(int i,int j,char color);

int    main(void)

{

    cin >> N >> M;

    for(int i = 1;i <= N;i ++)

        cin >> MAP[i] + 1;

    for(int i = 1;i <= N;i ++)

        for(int j = 1;j <= M;j ++)

        {

            VIS[i][j] = 1;

            if(dfs(i,j,MAP[i][j]))

            {

                puts("Yes");

                return    0;

            }

            VIS[i][j] = 0;

        }

    puts("No");



    return    0;

}



bool    dfs(int i,int j,char color)

{

    int    back_x = BACK_X;

    int    back_y = BACK_Y;

    for(int k = 0;k < 4;k ++)

    {

        int    next_x = i + UPDATE[k][0];

        int    next_y = j + UPDATE[k][1];



        if(next_x > N || next_x < 1 || next_y > M || next_y < 1 ||

           MAP[next_x][next_y] != color)

            continue;

        if(VIS[next_x][next_y] && next_x != BACK_X && next_y != BACK_Y)

        {

            return    true;

        }

        if(VIS[next_x][next_y])

            continue;



        BACK_X = i;

        BACK_Y = j;

        VIS[next_x][next_y] = 1;

        if(dfs(next_x,next_y,color))

            return    true;

        VIS[next_x][next_y] = 0;

        BACK_X = back_x;

        BACK_Y = back_y;

    }



    return    false;

}

 

你可能感兴趣的:(DFS)