https://www.luogu.org/problemnew/show/P1162
题目描述
由数字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。
输出格式:
已经填好数字2的完整方阵。
输入输出样例
输入样例#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
说明
1≤n≤30
解题思路:
bfs标记闭合圈外的0。
从边界开始如果一个数为0且没有被访问过,就开始遍历它周围的0。
因为处于边界的0,一定是闭合圈外的。
#include <stdio.h>
#define N 50
int a[N][N],book[N][N],n;
int next[4][2] = {
1,0, -1,0, 0,1, 0,-1
};
struct data {
int x;
int y;
}d[N*N];
void bfs(int x,int y)
{
int i,tx,ty;
book[x][y] = 1;
a[x][y] = 2;
int head=0;
int tail=1;
d[0].x = x;
d[0].y =y;
while(head < tail)
{
for(i=0; i<4; i++)
{
tx=d[head].x+next[i][0];
ty=d[head].y+next[i][1];
if(tx>=0 && tx<n && ty>=0 && ty<n && book[tx][ty]==0 && a[tx][ty]==0)
{
d[tail].x = tx;
d[tail].y = ty;
book[tx][ty] = 1;
a[tx][ty] = 2;
tail++;
}
}
head++;
}
}
int main()
{
int i,j;
scanf("%d", &n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
scanf("%d", &a[i][j]);
for(i=0; i<n; i++)
{
if(a[i][0]==0 && book[i][0]==0)
bfs(i,0);
if(a[0][i]==0 && book[0][i]==0)
bfs(0,i);
if(a[i][n-1]==0 && book[i][n-1]==0)
bfs(i,n-1);
if(a[n-1][i]==0 && book[n-1][i]==0)
bfs(n-1,i);
}
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
if(a[i][j]==0)
printf("2 ");
else if(a[i][j]==2)
printf("0 ");
else
printf("%d ", a[i][j]);
printf("
");
}
return 0;
}