信奥赛CSP-J复赛集训(dfs专题-刷题题单及题解)(2):洛谷P1162:填涂颜色
题目描述
由数字 0 0 0 组成的方阵中,有一任意形状的由数字 1 1 1 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 2 2 2。例如: 6 × 6 6\times 6 6×6 的方阵( n = 6 n=6 n=6),涂色前和涂色后的方阵如下:
如果从某个 0 0 0 出发,只向上下左右 4 4 4 个方向移动且仅经过其他 0 0 0 的情况下,无法到达方阵的边界,就认为这个 0 0 0 在闭合圈内。闭合圈不一定是环形的,可以是任意形状,但保证闭合圈内的 0 0 0 是连通的(两两之间可以相互到达)。
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 1 0 1
1 1 1 1 1 1
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 1 2 1
1 1 1 1 1 1
输入格式
每组测试数据第一行一个整数 n ( 1 ≤ n ≤ 30 ) n(1 \le n \le 30) n(1≤n≤30)。
接下来 n n n 行,由 0 0 0 和 1 1 1 组成的 n × n n \times n n×n 的方阵。
方阵内只有一个闭合圈,圈内至少有一个 0 0 0。
输出格式
已经填好数字 2 2 2 的完整方阵。
样例 #1
样例输入 #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
提示
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 30 1 \le n \le 30 1≤n≤30。
AC代码(100分)
#include<bits/stdc++.h>
using namespace std;
/*深搜思路: 原有方阵:1到n行,1到n列在原有方阵的外围加上一圈0:0到n+1行,0到n+1列 从dfs(0,0)开始泛洪去找所有外围的0,将其染色成3 经过dfs搜索后,我们的方阵就变成了外围是3,中间是1,内层是0然后if判断输出想要的结果即可
*/
int n,a[40][40];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
void dfs(int x,int y){a[x][y]=3;//将外围的0染色成3int nx,ny;for(int i=0;i<=3;i++){nx=x+dx[i];ny=y+dy[i];//注意边界的判断条件是扩大后的方阵边界 if(nx>=0 && nx<=n+1 && ny>=0 && ny<=n+1 && a[nx][ny]==0){dfs(nx,ny);} }
}
int main(){cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>a[i][j];}}//深搜 dfs(0,0);//关键点:从0,0开始搜索 //输出 for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(a[i][j]==3) cout<<0<<" ";else if(a[i][j]==1) cout<<1<<" ";else cout<<2<<" ";}cout<<endl;}return 0;
}
文末彩蛋:
点击王老师青少年编程主页有更多精彩内容