题目
题目描述
由数字00组成的方阵中,有一任意形状闭合圈,闭合圈由数字11构成,围圈时只走上下左右44个方向。现要求把闭合圈内的所有空间都填写成22.例如:6 \times 66×6的方阵(n=6n=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 \le n \le 30)n(1≤n≤30)
接下来nn行,由00和11组成的n \times nn×n的方阵。
方阵内只有一个闭合圈,圈内至少有一个00。
输出格式
已经填好数字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
说明/提示
1 \le n \le 301≤n≤30
分析
我的方法比较的讨巧。先利用dfs搜索到第一个唯一的点p,这时,我们可以发现需要填涂的点的八个方向都是被1围起来的,所以如果我们只按右和下进行搜索,那么需要填涂的点一定在p点的左下和右下,此时需要考虑三种情况:
- 第一个点,也就是(0,0)为1,需要填涂的点在p点的右下方;
- 如果p点右边为0或着p点为右边界时,需要填涂的点在p点的左下方;
- 否则需要填涂的点均在右下方。
找到第一个填涂点后,进行bfs,先将该点入队,入队的是该店的行列坐标,再进行该点四个方向的搜索,找到不为1或不为2的点就将该点置2并入队。队列为空时说明搜索完成。
如果还不太理解,具体的代码解释可以见我的代码注释哦~
代码
//1162
#include<iostream>
#include<queue>
using namespace std;
const int N = 35;
int n;
int map[N][N];
int ans[N][N];
int d[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
int yi[3]; //yi[0]yi[1]分别存储填涂起点行列坐标,yi[2]=1表示已找到填涂点
void dfs(int x,int y){ //搜索为1的点
if(map[x][y] == 1){ //遇到第一个就是1的点,则表明需要填涂的点在右下角
yi[0] = x+1;
yi[1] = y+1;
yi[2] = 1;
return;
}
for(int i = 0;i < 2;i++){ //只需向右和下移动即可找到该点
int xx = x + d[i][0];
int yy = y + d[i][1];
if(xx < 0 || xx >= n || yy < 0 || yy >= n) //边界判定
continue;
if(map[xx][yy] == 1){ //找到第一个为1的点,现在只有两种情况
if(map[xx][yy+1]==0 && yy+1==n){ //需要填涂的点在左下方时
yi[0] = xx+1;
yi[1] = yy-1;
}else{ //需要填涂的点在右下方时
yi[0] = xx+1;
yi[1] = yy+1;
}
yi[2] = 1;
return;
}
dfs(xx,yy);
if(yi[2] == 1){ //已找到该点,需要立即返回
return;
}
}
}
void bfs(int x,int y){//从第一个填涂点开始广搜
map[x][y] = 2; //将原始填涂点置2
queue<int> q;
//行列坐标入队
q.push(x);
q.push(y);
while(!q.empty()){
int xx = q.front();
q.pop();
int yy = q.front();
q.pop();
//搜索每个点上下左右的点
for(int i = 0;i < 4;i++){
int xxx = xx + d[i][0];
int yyy = yy + d[i][1];
if(map[xxx][yyy] != 1 && map[xxx][yyy] != 2){ //可以填涂
map[xxx][yyy] = 2;
q.push(xxx); //将新点入队
q.push(yyy);
}
}
}
}
int main(){
cin>>n;
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
cin>>map[i][j];
}
}
dfs(0,0);
bfs(yi[0],yi[1]);
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
cout<<map[i][j]<<" ";
}
cout<<endl;
}
return 0;
}