题目选自洛谷P1162
首先讲一下思路:根据题意,当找到第一个1时,其右下必然是圈内的0,那么只要从这个0开始广搜寻找联通块就可以了。(因为圈只有一个,那么当找到第一个1之后便要打断循环,很重要!)
题目描述
由数字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
解题代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int n,a[31][31];
int nt[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
struct dian{
int xx,yy;
};
queue<dian> q;
void print(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j!=1) cout<<" ";
cout<<a[i][j];
}
cout<<endl;
}
}
void bfs(int x,int y){
a[x][y] = 2;
q.push(dian{x,y});
int nx,ny;
while(!q.empty()){
dian ft = q.front();
for(int i=0;i<4;i++){
nx = ft.xx+nt[i][0]; ny = ft.yy+nt[i][1];
if(nx>=1&&nx<=n&&ny>=1&&ny<=n &&a[nx][ny]==0){
a[nx][ny] = 2;
q.push(dian{nx,ny});
}
}
q.pop();
}
}
int main(){
bool flag=false;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{cin>>a[i][j];}
int x=0,y=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]==1){x=i+1,y=j+1;flag=true;break;}
}
if(flag) break;
}
bfs(x,y);
print();
return 0;
}