洛谷 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(1≤n≤30)
接下来 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≤n≤30
解题分析:
题目要求我们找出图中唯一的由0组成的闭合圈,然后将这个闭合圈中的所有0全部置为2,输出。注意,要将这里的闭合圈和联通块区分,因为这里不仅仅是要求是0的联通块,并且这个联通块的周围必须是由1全包围。
解题的突破口就是要发现,如果某一由0组成的联通块有在边界上的0,那么该连通块必然不可能是闭合圈(因为该0已是边界,不可能被1全包围),所以我们对每一个边界上的0进行深搜,将由他们延伸出来的连通块
全部标记,最后,图中没有标记的0必然属于闭合。
#include <bits/stdc++.h> using namespace std; #define RP(i,s,t) for(int i=s;i<=t;i++) const int N = 35; int g[N][N],vis[N][N]; int n; const 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] || g[xx][yy]==1 ) continue; dfs(xx,yy); } } int main(){ scanf("%d",&n); RP(i,1,n) RP(j,1,n) scanf("%d",&g[i][j]); RP(i,1,n) RP(j,1,n) { if((i==1 || j==1 || i==n || j==n ) && g[i][j]==0) dfs(i,j); } RP(i,1,n){ RP(j,1,n) { if( g[i][j]==0 && !vis[i][j] ) g[i][j]=2; printf("%d ",g[i][j]); } puts(""); } }
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。