首先,分析题目,这是要将闭合的“1”里面的“0”改写成“2”,然后输出。由此,我们猛然发觉,只要‘0’的联通块中,没有在边界的就是闭合的‘0’;(发现这个,就等于做对了一半;)
因为,从正面推,找闭合中的‘0’不好找。所以运用BFS或者DFS直接搜索边界中‘0’,所在的联通块,然后标记。
最后输出时,去除‘1’点和标记了的点,剩下的输出为‘2’,就是正解啦!!!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
const int MAX=0x3f3f3f3f;
const int N=50;
int n;
int a[N][N];
bool vis[N][N];
int dx[4]={0, -1, 0, 1};
int dy[4]={-1, 0, 1, 0};
void dfs(int x,int y){
vis[x][y]=1; //说明这个点是没有闭合的0,不需要变成2
for(int i=0;i<4;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<n&&!vis[nx][ny]&&a[nx][ny]==0){
dfs(nx,ny);
}
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==0||j==0||i==n-1||j==n-1){
if(a[i][j]==0&&!vis[i][j]){
dfs(i,j); //对边界上的点进行连通块判断
}
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(j!=0) cout<<" "; //第一列不需要空格
if(vis[i][j]) cout<<"0";
else if(a[i][j]) cout<<"1";
else cout<<"2";
}
cout<<endl;
}
}