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

题目描述

由数字 0 组成的方阵中,有一任意形状的由数字 1 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 2。例如:6×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(1n30)

接下来 n 行,由 01 组成的 n×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% 的数据,1n30

题解

#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;
}
发布于   xiins  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示