目录
1233. 全球变暖
输入格式
输出格式
数据范围
输入样例1:
输出样例1:
输入样例2:
输出样例2:
思路:
宽搜BFS 模板:
代码:
运行结果:
1233. 全球变暖
你有一张某海域 N×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 22 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入格式
第一行包含一个整数N。
以下 NN 行 NN 列,包含一个由字符”#”和”.”构成的 N×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。
照片保证第 1行、第 1 列、第 N 行、第 N 列的像素都是海洋。
输出格式
一个整数表示答案。
数据范围
1≤N≤1000
输入样例1:
7
.......
.##....
.##....
....##.
..####.
...###.
.......
输出样例1:
1
输入样例2:
9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........
输出样例2:
1
难度:简单 |
时/空限制:1s / 64MB |
来源: 第九届蓝桥杯省赛C++ A组/B组第九届蓝桥杯省赛Java A组/B组 |
算法标签 Flood Fill BFS DFS |
思路:
-
- 读取包含陆地('#')和大海('.')的地图数据。
- 对地图进行遍历,对每个未被搜索过的陆地进行广度优先搜索(BFS),统计搜索到的陆地单元格数(total)和与大海相连的边界单元格数(bound)。
- 判断一个岛屿是否被完全淹没的标准是:搜索到的陆地单元格数等于与大海相连的边界单元格数。若满足此条件,计数器
cnt
加一。
宽搜BFS 模板:
代码:
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n;
char g[N][N]; // 二维数组 g 存储地图,'#' 表示陆地,'.' 表示大海
bool st[N][N]; // 记录每个格子是否被搜索过,初始均为 false
PII q[N * N]; // 定义一个队列用于广度优先搜索
int dx[4] = {-1, 0, 1, 0}; // 四个方向的水平偏移量
int dy[4] = {0, 1, 0, -1}; // 四个方向的垂直偏移量
// 广度优先搜索函数,参数:搜索起点坐标(sx, sy),累计搜索到的陆地单元格数(total),与大海相连的边界单元格数(bound)
void bfs(int sx, int sy, int &total, int &bound) {
int hh = 0, tt = 0; // hh:队首指针,tt:队尾指针
q[0] = {sx, sy}; // 将起点加入队列
st[sx][sy] = true; // 标记起点已被搜索过
while (hh <= tt) { // 当队列不为空时
PII t = q[hh++]; // 弹出队首元素
total++; // 增加已搜索到的陆地单元格数
bool is_bound = false; // 标记当前格子是否与大海相连
// 遍历当前格子的四个方向
for (int i = 0; i < 4; i++) {
int x = t.x + dx[i], y = t.y + dy[i]; // 计算相邻格子坐标
// 检查是否越界
if (x < 0 || x >= n || y < 0 || y >= n) continue;
// 如果相邻格子已被搜索过,跳过本次循环
if (st[x][y]) continue;
// 检查相邻格子类型
if (g[x][y] == '.') {
is_bound = true; // 标记当前格子与大海相连
continue;
}
// 如果相邻格子是未搜索过的陆地,将其加入队列并标记为已搜索
q[++tt] = {x, y};
st[x][y] = true;
}
// 如果当前格子与大海相连,增加边界单元格数
if (is_bound) bound++;
}
}
int main() {
scanf("%d", &n); // 输入地图大小
// 读取地图数据
for (int i = 0; i < n; i++) scanf("%s", g[i]);
int cnt = 0; // 初始化被淹没岛屿个数
// 遍历地图,对每个未被搜索过的陆地进行广度优先搜索
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
if (!st[i][j] && g[i][j] == '#') { // 检查是否为未搜索过的陆地
int total = 0, bound = 0; // 初始化单元值和边界数量
bfs(i, j, total, bound); // 对当前陆地进行广度优先搜索
// 如果搜索到的陆地单元格数等于与大海相连的边界单元格数,说明该岛屿被完全淹没,计数器加一
if (total == bound) cnt++;
}
}
printf("%d\n", cnt); // 输出被淹没岛屿个数
return 0;
}