侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 674 篇文章
  • 累计创建 128 个标签
  • 累计收到 20 条评论

目 录CONTENT

文章目录

【BFS】全球变暖【蓝桥杯】

GabrielxD
2022-12-19 / 0 评论 / 0 点赞 / 91 阅读 / 961 字
温馨提示:
本文最后更新于 2023-02-07,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

1233. 全球变暖

全球变暖 - 蓝桥云课


你有一张某海域 N×NN \times N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:

.......
.##....
.##....
....##.
..####.
...###.
.......

其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 22 座岛屿。

由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。

具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

例如上图中的海域未来会变成如下样子:

.......
.......
.......
.......
....#..
.......
.......

请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

输入格式

第一行包含一个整数N。

以下 NNNN 列,包含一个由字符”#”和”.”构成的 N×NN \times N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。

照片保证第 11 行、第 11 列、第 NN 行、第 NN 列的像素都是海洋。

输出格式

一个整数表示答案。

数据范围

1N10001 \le N \le 1000

输入样例1:

7
.......
.##....
.##....
....##.
..####.
...###.
.......

输出样例1:

1

输入样例2:

9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........

输出样例2:

1

解题

方法一:BFS

思路

遍历+BFS

遍历矩阵,如果遇到陆地就进入 BFS 把这个岛屿宽搜出来,同时判断这个岛屿有没有能剩下的陆地(四面不全是水),如果宽搜完后发现该岛屿没有任何一块能剩下来的陆地,就说明多了一个被完全淹没的岛屿(ans++)。

注意:每次宽搜都要搜索完整个岛屿并做上标记以防止下一次遍历到同一片岛屿。

代码

#include <iostream>
#include <limits>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

const int N = 1010, DIRS[][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int n;
char g[N][N];

int bfs(int x, int y) {
    int flag = false;
    queue<PII> que;
    que.push({x, y});
    g[x][y] = '*';
    while (!que.empty()) {
        auto pr = que.front();
        que.pop();
        x = pr.first, y = pr.second;
        bool disappear = false;
        for (auto& DIR : DIRS) {
            int nx = x + DIR[0], ny = y + DIR[1];
            if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
            if (g[nx][ny] == '.') disappear = true;
            if (g[nx][ny] == '#') {
                que.push({nx, ny});
                g[nx][ny] = '*';
            }
        }
        if (!disappear) flag = true;
    }
    return !flag;
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        for (int j = 0; j < n; ++j) {
            scanf("%c", &g[i][j]);
        }
    }
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (g[i][j] == '#') cnt += bfs(i, j);
        }
    }
    printf("%d\n", cnt);
    
    return 0;
}
import java.util.*;
import java.io.*;

public class Main {
    static final int[][] DIRS = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    static int n;
    static char[][] g;
    static int ans = 0;
    static Queue<int[]> que = new LinkedList<>();

    static int bfs(int x, int y) {
        que.clear();
        que.offer(new int[]{x, y});
        g[x][y] = '*';
        boolean disapper = true;
        while (!que.isEmpty()) {
            int[] curr = que.poll();
            x = curr[0];
            y = curr[1];
            boolean fade = false;
            for (int[] DIR : DIRS) {
                int nx = x + DIR[0], ny = y + DIR[1];
                if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
                if (g[nx][ny] == '.') fade = true;
                else if (g[nx][ny] == '#') {
                    que.offer(new int[]{nx, ny});
                    g[nx][ny] = '*';
                }
            }
            if (!fade) disapper = false;
        }
        return disapper ? 1 : 0;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StreamTokenizer in = new StreamTokenizer(br);
        in.nextToken();
        n = (int) in.nval;
        g = new char[n][n];
        for (int i = 0; i < n; ++i) g[i] = br.readLine().toCharArray();
        int cnt = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (g[i][j] == '#') cnt += bfs(i, j);
            }
        }
        System.out.println(cnt);
    }
}
0

评论区