思路:
由题目可知,需要被填涂的部分只有一块,且它被依托“1”包裹着,也就是说图中的“0”不是接触边界就是被“1”包裹,因此我们可以枚举边界的0,并把它们全部标上“3”,再遍历整个图,把剩下的0全部标成2,最后把所有3都改回0,具体看代码。
#include<iostream>
#include<queue>
using namespace std;
#define maxn (3*10+3)
int a[maxn][maxn]={};
bool vis[maxn][maxn]={};
int dx[]={0, -1, 0, 1};
int dy[]={-1, 0, 1, 0};//偏移数组
struct pos{
int x, y;
};
queue<pos> p;
int n;
void bfs(int x, int y){//这里的x和y都是确定好的边界0的坐标
while(!p.empty()){
pos now=p.front();
p.pop();
x=now.x;
y=now.y;
for(int i=0;i<4;i++){
int newx=x+dx[i];
int newy=y+dy[i];
if(newx>=0 && newx<n && newy>=0 && newy<n && a[newx][newy]!=1 && !vis[newx][newy]){
p.push(pos{newx, newy});
vis[newx][newy]=true;//剪枝操作
a[newx][newy]=3;//把边界的0都标成3
}
}
}
}//bfs模板
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
int x=0, y=0;
for(int i=0;i<n;i++){
if(a[0][i]==0){
x=0;
y=i;
p.push(pos{x, y});
a[x][y]=3;
bfs(x, y);
}
}
for(int i=0;i<n;i++){
if(a[i][0]==0){
x=i;
y=0;
p.push(pos{x, y});
a[x][y]=3;
bfs(x, y);
}
}
for(int i=0;i<n;i++){
if(a[n-1][i]==0){
x=n-1;
y=i;
p.push(pos{x, y});
a[x][y]=3;
bfs(x, y);
}
}
for(int i=0;i<n;i++){
if(a[i][n-1]==0){
x=i;
y=n-1;
p.push(pos{x, y});
a[x][y]=3;
bfs(x, y);
}
}//分别枚举每条边的0并且进行bfs
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i][j]==0){
a[i][j]=2;//填涂
}
else if(a[i][j]==3){
a[i][j]=0;//把边界0改回去
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;//输出
}
return 0;
}