由数字 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。
输出格式
已经填好数字 22 的完整方阵。
输入输出样例
输入
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
说明/提示
反过来考虑这个问题,判断在圈里面不容易,但判断在圈外面很容易
沿着最外层遍历一圈,从最外层的0开始搜索,可以访问到所有封闭的圈以外的0,标记为3;
打印:3打印为0,1还是打印为1,0打印为2;
#include <bits/stdc++.h>
using namespace std;
int n;
int a[40][40];
//方向值的变化数组
int fx[5] = {0,0,1,0,-1};
int fy[5] = {0,1,0,-1,0};
//深搜:从xy点开始搜索,将所有相邻的0标记为3
void dfs(int x,int y){
a[x][y] = 3;
//遍历四方向
int tx,ty;
for(int i = 1;i <= 4;i++){
tx = x + fx[i];
ty = y + fy[i];
//判断在方阵内,且要去的点是0
if(tx>=1&&tx<=n&&ty>=1&&ty<=n&&a[tx][ty]==0) dfs(tx,ty);
}
}
int main() {
cin>>n;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
cin>>a[i][j];
}
}
//遍历最外层的值,找到0,深搜
//第1行和最后一行,一定在最外层,其余每行只有第1个和最后一个在最外层
//循环每一行
for(int i = 1;i <= n;i++){
//只有第1行和最后一行要循环每一列
if(i == 1 || i == n){
for(int j = 1;j <= n;j++){
if(a[i][j] == 0) dfs(i,j);
}
}else{
//看第1个和最后一个值
if(a[i][1] == 0) dfs(i,1);
if(a[i][n] == 0) dfs(i,n);
}
}
//打印
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] == 0) cout<<2<<" ";
else cout<<1<<" ";
}
cout<<endl;
}
return 0;
}