题解 | 没挡住洪水

没挡住洪水

https://www.nowcoder.com/practice/6d62436fda5f4ef997e68d1ce1dd6eb2

import java.io.*;
import java.util.*;

public class Main {
    /**
     * 主方法,用于处理输入并计算连通分量的数量
     *
     * @param args 命令行参数
     * @throws IOException 可能抛出的IO异常
     */
    public static void main(String[] args) throws IOException {
        // 使用BufferedReader读取输入,使用PrintWriter输出结果
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));


        // 读取网格大小N
        int N = Integer.parseInt(br.readLine().trim());
        // 创建N×N的网格数组
        char[][] grid = new char[N][N];
        // 创建N×N的访问标记数组
        boolean[][] visit = new boolean[N][N];

        // 读取网格数据
        for (int i = 0; i < N; i++) {
            grid[i] = br.readLine().trim().toCharArray();
        }

        // 初始化答案计数器
        int ans = 0;

        // 遍历网格中的每个位置
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                // 如果当前位置是'#'且未被访问过
                if (grid[i][j] == '#' && !visit[i][j]) {
                    // 执行BFS,如果BFS返回false,则增加连通分量计数
                    if (!bfs(grid, N, i, j, visit)) {
                        ans++;
                    }
                }
            }
        }
        // 输出结果并关闭所有资源
        out.println(ans);
        out.flush();
        out.close();
        br.close();

    }

    /**
     * 使用广度优先搜索(BFS)算法检查一个区域是否能够存活
     *
     * @param grid  二维字符数组,表示网格状态,'#'表示存活,'.'表示死亡
     * @param N     网格的大小,N x N
     * @param i     起始行坐标
     * @param j     起始列坐标
     * @param visit 二维布尔数组,记录每个位置是否被访问过
     * @return 如果区域存活返回true,否则返回false
     */
    private static boolean bfs(char[][] grid, int N, int i, int j, boolean[][] visit) {
        // 创建队列用于BFS遍历
        Queue<int[]> queue = new LinkedList<>();
        // 将起始位置加入队列并标记为已访问
        queue.add(new int[]{i, j});
        visit[i][j] = true;
        // 标记区域是否存活,初始为false
        boolean areaSurvived = false;

        // 定义四个方向:上、下、左、右
        int[] dx = {-1, 1, 0, 0};
        int[] dy = {0, 0, -1, 1};

        // 当队列不为空时,继续BFS遍历
        while (!queue.isEmpty()) {
            // 取出队列中的当前位置
            int[] cur = queue.poll();
            int x = cur[0];
            int y = cur[1];

            // 标记当前位置是否完全被存活区域包围
            boolean flag = true;

            // 检查四个方向
            for (int k = 0; k < 4; k++) {
                int nextX = x + dx[k];
                int nextY = y + dy[k];

                // 如果相邻位置超出边界或为死亡状态,则当前位置不被完全包围
                if (nextX < 0 || nextX >= N || nextY < 0 || nextY >= N || grid[nextX][nextY] == '.') {
                    flag = false;
                    break;
                }
            }

            // 如果当前位置被完全包围,则标记区域存活
            if (flag) {
                areaSurvived = true;
            }

            // 遍历四个方向,将相邻的存活且未访问的位置加入队列
            for (int k = 0; k < 4; k++) {
                int nextX = x + dx[k];
                int nextY = y + dy[k];

                // 检查相邻位置是否在网格内、为存活状态且未被访问
                if (nextX >= 0 && nextX < N && nextY >= 0 && nextY < N && grid[nextX][nextY] == '#' && !visit[nextX][nextY]) {
                    // 标记为已访问并加入队列
                    visit[nextX][nextY] = true;
                    queue.add(new int[]{nextX, nextY});
                }
            }
        }
        // 返回区域是否存活的最终结果
        return areaSurvived;
    }
}

全部评论

相关推荐

肖先生~:大一点得到公司面试更能学到点东西
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务