[LUOGU] P1162 填涂颜色

题目描述

由数字0
组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。现要求把闭合圈内的所有空间都填写成2.例如:6X6的方阵(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 1 1
1 1 1 1 1 1
输入输出格式

输入格式: 每组测试数据第一行一个整数:n。其中n(1<=n<=30)

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

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

//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)

输出格式: 已经填好数字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 1 1
1 1 1 1 1 1
说明
1<=n<=30

最初有两种(失败的)思路:
1.每一列从上往下,找到第一个1就开始填充 ,再找到1停,40分。是会有一列多个1的情况,就先判断一共多少个1,进行(n-1)轮填充,只有60分,毕竟考虑不周到,如果人家不闭合呢?
2.正常的思路dfs,先dfs1找到一个1,再dfs2找到0,再dfs3填充内部的0,非常冗长,错误挺多,调半天,60分。

最正确的思路!【敲黑板】
先“平窜”整个01图,从(1,1)开始存,就是把周围一圈空出来,保证最边上的0都可以被连通起来,然后dfs从(0,0)开始扫,找到0变成3,扫完外面的0,剩下的就是内部的0了,然后把0置为2,3置为0,输出。

PS:还有点小插曲,每个数字间的空格一开始没写,导致爆0。哎。

#include<iostream>
#include<cstdio>
using namespace std;

int a[35][35];
int n;

void dfs(int x,int y){
    if(x>=0&&x<=n+1&&y>=0&&y<=n+1){
        if(a[x][y]==1||a[x][y]==3) return;
        else{
            a[x][y]=3;
            dfs(x+1,y);
            dfs(x-1,y);
            dfs(x,y+1);
            dfs(x,y-1);
        }
    }
}

int main(){
    cin>>n;
    int i,j;
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            cin>>a[i][j];
        }
    }
    dfs(0,0);
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            if(a[i][j]==0) a[i][j]=2;
            if(a[i][j]==3) a[i][j]=0;

        }
    }
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
} 

本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247552.html

原文地址:https://www.cnblogs.com/ghostcai/p/9247552.html