1233. 全球变暖---BFS

发布于:2024-04-14 ⋅ 阅读:(113) ⋅ 点赞:(0)

目录

 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

思路:

    1. 读取包含陆地('#')和大海('.')的地图数据。
    2. 对地图进行遍历,对每个未被搜索过的陆地进行广度优先搜索(BFS),统计搜索到的陆地单元格数(total)和与大海相连的边界单元格数(bound)。
    3. 判断一个岛屿是否被完全淹没的标准是:搜索到的陆地单元格数等于与大海相连的边界单元格数。若满足此条件,计数器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;
}

运行结果:


网站公告

今日签到

点亮在社区的每一天
去签到