• 洛谷 P1162 填涂颜色【DFS】


    题目链接:https://www.luogu.org/problemnew/show/P1162

    题目描述

    由数字 0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字 1 构成,围圈时只走上下左右 4 个方向。现要求把闭合圈内的所有空间都填写成 2 .例如: 6 ×6 的方阵( n=6 ),涂色前和涂色后的方阵如下:

    0 0 0 0 0 0
    0 0 1 1 1 1
    0 1 1 0 0 1
    1 1 0 0 0 1
    1 0 0 0 0 1
    1 1 1 1 1 1
    0 0 0 0 0 0
    0 0 1 1 1 1
    0 1 1 2 2 1
    1 1 2 2 2 1
    1 2 2 2 2 1
    1 1 1 1 1 1

    输入格式: 

    每组测试数据第一行一个整数n(1n30) 

    接下来 n 行,由 0 和 1 组成的n×n 的方阵。 

    方阵内只有一个闭合圈,圈内至少有一个 0 。

    输出格式: 

    已经填好数字 2 的完整方阵。

    输入样例#1:
    6
    0 0 0 0 0 0
    0 0 1 1 1 1
    0 1 1 0 0 1
    1 1 0 0 0 1
    1 0 0 0 0 1
    1 1 1 1 1 1
    
    输出样例#1: 
    0 0 0 0 0 0
    0 0 1 1 1 1
    0 1 1 2 2 1
    1 1 2 2 2 1
    1 2 2 2 2 1
    1 1 1 1 1 1 

    说明 

    1n30

    解题分析:
    题目要求我们找出图中唯一的由0组成的闭合圈,然后将这个闭合圈中的所有0全部置为2,输出。注意,要将这里的闭合圈和联通块区分,因为这里不仅仅是要求是0的联通块,并且这个联通块的周围必须是由1全包围。

    解题的突破口就是要发现,如果某一由0组成的联通块有在边界上的0,那么该连通块必然不可能是闭合圈(因为该0已是边界,不可能被1全包围),所以我们对每一个边界上的0进行深搜,将由他们延伸出来的连通块

    全部标记,最后,图中没有标记的0必然属于闭合(因为闭合圈只有一个)。

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int map[35][35];
    int vis[35][35];
    int n;
    int dir[][2] = {1,0,0,1,-1,0,0,-1};
    
    void dfs(int x, int y)
    {
        vis[x][y] = 1;
        for (int k = 0; k < 4; k++)
        {
            int xx = x + dir[k][0];
            int yy = y + dir[k][1];
            if (xx<1 || xx>n || yy<1|| yy>n || vis[xx][yy] || map[xx][yy] == 1)continue;       //如果不符合条件,则跳过
            dfs(xx, yy);
        }
    }
    
    int main()
    {
        cin >> n;
        for (int i = 1; i <=n; i++)
            for (int j = 1; j <= n; j++)
                scanf("%d", &map[i][j]);
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                if ((i == 1 || j == 1||i==n||j==n) && map[i][j] == 0)         //对边界上的0进行深搜
                {
                    dfs(i, j);                    //因为由这些边界上的0延伸出来的0不可能属于闭合圈,所以将它们标记
                } 
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++)
            {
                if (map[i][j] == 0 && !vis[i][j])map[i][j] = 2;
                printf("%d ", map[i][j]);
            }
            cout << endl;
        }
        return 0;
    }

    2018-05-30 

  • 相关阅读:
    Java中使用Jedis操作Redis
    Predicate与filter
    Joiner的用法
    Immutable集合
    【Excle数据透视】如何在数据透视表字段列表中显示更多的字段
    【Excle数据透视表】如何显示/隐藏数据透视表字段列表
    【Excle数据透视】如何创建多条件汇总的数据透视表
    【Excle数据透视表】如何创建非共享缓存的数据透视表
    【Excle数据透透视表】如何删除数据透视表
    【Excle数据透视表】如何复制数据透视表
  • 原文地址:https://www.cnblogs.com/00isok/p/9113589.html
Copyright © 2020-2023  润新知