P1162 填涂颜色——DFS、连通性

题目描述

由数字 \(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 改为 2
    for (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;
}
posted @ 2025-02-22 12:29  ToFuture$  阅读(38)  评论(0)    收藏  举报