题解 | 没挡住洪水
没挡住洪水
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;
}
}
