题目链接:P1162 填涂颜色
题目意思就是将1包围0变成2,直接做不好做,那我们反过来思考一下,我们可不可以对闭合的圈以外的数进行操作呢,这似乎比直接对圈内的数直接操作方便。
对于a数组,是我们读入数据的,我们再开一个b数组,初始全为2,若a[i][j]为1,则把b[i][j]设为1。
我们从边界开始进行bfs,bfs在a中可以走到的格子,并且这个格子为0,那么就把b数组中的这个格子也设为0,这样对于b数组而言,闭合圈外所有不为1的格子都变成了0,圈内仍然是2
#include<bits/stdc++.h>
using namespace std;
const int N = 35;
int a[N][N],b[N][N];
bool vis[N][N];
int n;
const int dx[4] = { 0, 0, -1, 1 }, dy[4] = { 1, -1, 0, 0 };
struct P{
int x, y;
P(int _x = 0, int _y = 0) :x(_x), y(_y){}
};
queue<P> que;
bool valid(int x, int y)
{
return x > 0 && y > 0 && x <= n&&y <= n&&a[x][y] == 0 && !vis[x][y];
}
void bfs()
{
for (int i = 1; i <= n; i++) //从边界为0的点开始bfs
{
if (a[1][i] == 0) que.push(P(1, i)),b[1][i]=0,vis[1][i]=true;
if (a[n][i] == 0) que.push(P(n, i)),b[n][i]=0,vis[n][i]=true;
if (a[i][1] == 0) que.push(P(i, 1)), b[i][1] = 0,vis[i][1]=true;
if (a[i][n] == 0) que.push(P(i, n)), b[i][n]=0,vis[i][n]=true;
}
while (!que.empty())
{
P cur = que.front();
que.pop();
for (int i = 0; i < 4; i++)
{
int nx = cur.x + dx[i], ny = cur.y + dy[i];
if (valid(nx, ny))
{
vis[nx][ny] = true;
b[nx][ny] = 0;
que.push(P(nx, ny));
}
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
cin >> a[i][j];
if (a[i][j] == 1) b[i][j] = 1;
else b[i][j] = 2;
}
bfs();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cout << b[i][j] << "
"[j == n];
return 0;
}