题目描述
由数字00组成的方阵中,有一任意形状闭合圈,闭合圈由数字11构成,围圈时只走上下左右44个方向。现要求把闭合圈内的所有空间都填写成2例如:6×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≤n≤30)
接下来nn行,由00和11组成的n×n的方阵。
方阵内只有一个闭合圈,圈内至少有一个00。
//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)
输出格式
已经填好数字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≤n≤30
思路:我们将矩阵外面扩展一层都为0,从mp[0][0]位置开始宽搜,将所有与起点向连的零统统标记起来,在我们用BFS遍历之后,输出矩阵,将没有标记的零输出2即可。
#include<cstdio>
#include<queue>
using namespace std;
int xx[]={0,-1,0,1};//方向
int yy[]={1,0,-1,0};
int mp[40][40];//地图
bool vis[40][40];//标记有没有访问过
int n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&mp[i][j]);//输入地图
}
}
queue<int>x;//用x队列记录x的状态
queue<int>y;//用y队列记录y状态
x.push(0);//压入起始点
y.push(0);//压入起始点
vis[0][0]=true;//标记起始点访问过
while(!x.empty()){//判断队列是否为空
for(int i=0;i<4;i++){//找当前点相邻的点
int dx=x.front()+xx[i];
int dy=y.front()+yy[i];
if(dx>=0&&dx<=n+1&&dy>=0&&dy<=n+1&&mp[dx][dy]==0&&!vis[dx][dy]){
x.push(dx);//相邻的点压入队列
y.push(dy);
vis[dx][dy]=true;
}
}
x.pop();//当前点任务完成出队
y.pop();//当前点任务完成出队
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(mp[i][j]==0&&!vis[i][j]){
printf("%d ",2);//将闭合圈内的0输出为2
}else{
printf("%d ",mp[i][j]);
}
}
printf("\n");
}
return 0;
}