题目描述
由数字 \(0\) 组成的方阵中,有一任意形状的由数字 \(1\) 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 \(2\)。例如:\(6\times 6\) 的方阵(\(n=6\)),涂色前和涂色后的方阵如下:
如果从某个 \(0\) 出发,只向上下左右 \(4\) 个方向移动且仅经过其他 \(0\) 的情况下,无法到达方阵的边界,就认为这个 \(0\) 在闭合圈内。闭合圈不一定是环形的,可以是任意形状,但保证闭合圈内的 \(0\) 是连通的(两两之间可以相互到达)。
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 1 0 1
1 1 1 1 1 1
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 1 2 1
1 1 1 1 1 1
输入格式
每组测试数据第一行一个整数 \(n(1 \le n \le 30)\)。
接下来 \(n\) 行,由 \(0\) 和 \(1\) 组成的 \(n \times n\) 的方阵。
方阵内只有一个闭合圈,圈内至少有一个 \(0\)。
输出格式
已经填好数字 \(2\) 的完整方阵。
输入输出样例 #1
输入 #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
说明/提示
对于 \(100\%\) 的数据,\(1 \le n \le 30\)。
题解
#include <iostream>
#include <cstring>
using namespace std;const int MAXN = 35;
int a[MAXN][MAXN];
int n;
// 四个方向的偏移量
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};// 深度优先搜索函数,标记能到达边界的 0
void dfs(int x, int y) {// 判断越界或者不是 0 的情况if (x < 1 || x > n || y < 1 || y > n || a[y][x] != 0) {return;}// 标记为 -1,表示能到达边界a[y][x] = -1;for (int i = 0; i < 4; i++) {int nx = x + dx[i];int ny = y + dy[i];dfs(nx, ny);}
}int main() {cin >> n;memset(a, 0, sizeof(a));for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cin >> a[i][j];}}// 从边界的 0 开始进行深度优先搜索for (int i = 1; i <= n; i++) {if (a[1][i] == 0) dfs(i, 1);if (a[n][i] == 0) dfs(i, n);if (a[i][1] == 0) dfs(1, i);if (a[i][n] == 0) dfs(n, i);}// 将未被标记的 0 改为 2for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {if (a[i][j] == 0) {a[i][j] = 2;} else if (a[i][j] == -1) {a[i][j] = 0;}}}// 输出结果for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cout << a[i][j] << " ";}cout << endl;}return 0;
}