题目描述
由数字 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。
//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)
输出格式
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有两种情况,一种是在包围范围内,另外一种是在包围范围外,为了区别这两种,我们使用另外一个数组(brr)来进行存储判断的结果,在判断函数中,我们使用队列来依次弹出数组来进行判断,队列弹出的数暂先使用结构体来存储数据,弹出数据后,在进行上下左右的判断,满足条件我们就进行标记,不满足就进行下一个判断。(纯暴力搜索,我们只需要对数组中的数一个一个进行判断,一个一个标记就可以了)。
//我们使用一个数组来存储数据,一个数组存储判断结果
//如果数组中一个数等于0的同时,又存在上下左右有等于1的,该数就被包裹在内数
//打印时如果该数等于0的同时,判断数组等于1,就为包裹的数
#include<bits/stdc++.h>
using namespace std;
int n,arr[35][35]={0},brr[35][35]={0},tmep;
struct point{
int x,y;
};
int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};//进行四周寻找,要确保相加等于0
queue<point> q;
void intput()
{
brr[0][0]=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&tmep);
if(tmep!=0)
arr[i][j]=1;
}
}
void print()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(arr[i][j]==0&&brr[i][j]==0)//注意判断条件
printf("2 ");
else if(arr[i][j]==1)
printf("1 ");
else
printf("0 ");
}
printf("\n");
}
}
void judge()
{
q.push(point{0,0});
while(!q.empty())//将闭合区间外面的0全部标记为1
{
point p=q.front();//找到队列中的队列的第一个元素
q.pop();//在不断进行删除第一个元素
for(int i=0;i<4;i++)
{
int x=p.x+dx[i];
int y=p.y+dy[i];
if(x<0||x>n+1||y<0||y>n+1)//越界情况
continue;
if(arr[x][y]==0&&brr[x][y]==0)//为0且未被搜索过
{
brr[x][y]=1;
q.push(point{x,y});
}
}
}
}
int main()
{
intput();
judge();
print();
return 0;
}