zoukankan      html  css  js  c++  java
  • 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:

    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;
    }
  • 相关阅读:
    通过使用 SQL,可以为列名称和表名称指定别名(Alias)
    BETWEEN 操作符
    IN 操作符
    SQL 通配符
    LIKE 操作符
    TOP 子句
    DELETE 语句
    Update 语句
    INSERT INTO 语句
    IOS SWIFT 网络请求JSON解析 基础一
  • 原文地址:https://www.cnblogs.com/xz816111/p/4452166.html
Copyright © 2011-2022 走看看