题目描述
由数字0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。现要求把闭合圈内的所有空间都填写成2.例如:6X6的方阵(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。其中n(1<=n<=30)
接下来n行,由0和1组成的nXn的方阵。
方阵内只有一个闭合圈,圈内至少有一个0。
//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)
输出格式:
已经填好数字2的完整方阵。
刚开始觉得很简单,不就是从外面往里面bfs嘛。
第一次提交直接从第一个圈子外面的0开始搜,暴0。
然后意识到可能中间会被1的圈子断开,于是第二次从四个角往里搜,60,还是没过。
然后发现还可能有以下这种特殊情况:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 1 1 1 1 1 1
0 1 0 0 0 0 1
0 1 0 0 0 0 1
0 1 1 1 1 0 1
0 1 1 0 1 1 1
最后一排的0被两边的0断开,看来只有从每条边都找一遍。
太蠢了吧,竟然暴0。然后发现如果开始的点如果是1,就会往圈子里面搜,最后所有都会变成0。悲伤。
放代码(抱紧我的垃圾程序瑟瑟发抖
(如果数据大也不知道跑得动不,应该有很多优化点可是还没学…只能将就看一下吧…
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=35,maxm=1000;
const int zl[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
int n,a[maxn][maxn],color[maxn][maxn];
struct node{
int x,y;
node():x(),y(){}
node (const int x,const int y):
x(x),y(y){}
};node q[maxm];
void bfs(int xx,int yy)
{
if(a[xx][yy]==1) return ;//防止往里面搜
int head=0,tail=1;
q[tail]=node(xx,yy);
color[xx][yy]=0;
while(head<tail)
{
head++;
node b=q[head];
for(int i=0;i<4;i++)
{
int x=b.x+zl[i][0],y=b.y+zl[i][1];
if(x>=0&&x<n&&y>=0&&y<n&&a[x][y]!=1&&color[x][y]==2){
q[++tail]=node(x,y);
color[x][y]=0;
}
}
}
}
int main()
{
cin>>n;
int k=0,t=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
cin>>a[i][j];
if(a[i][j]==1) color[i][j]=1;
else color[i][j]=2;//先把全部0改成2,再从每个边界向内缩小圈子
}
for(int i=0;i<n;i++){//从边的每个点往里面搜
bfs(i,0);
bfs(i,n-1);
bfs(0,i);
bfs(n-1,i);
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
cout<<color[i][j]<<" ";
cout<<endl;
}
return 0;
}