全球变暖
你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:
●●●●●●●
●##●●●●
●##●●●●
●●●●##●
●●####●
●●●###●
●●●●●●●
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
●●●●●●●
●●●●●●●
●●●●●●●
●●●●●●●
●●●●#●●
●●●●●●●
●●●●●●●
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入格式:
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行、第1列、第N行、第N列的像素都是海洋。
输出格式:
一个整数表示答案。
输入样例:
7
●●●●●●●
●##●●●●
●##●●●●
●●●●##●
●●####●
●●●###●
●●●●●●●
输出样例:
1
思路分析:
因为题目保证外圈都为海洋,所以开始从(1,1)坐标搜索,搜到“#”被淹没的岛屿数便加一,即num 自加。然后搜索该’#'的四周,若上下左右都不是“.”,说明该块区域四面被陆地包围,则该岛屿一定不会被淹没,淹没岛屿数num自减。然后调用change()函数将其四周与之相连的陆地区域都换成海洋“.”(可理解为我们手动淹没整个岛屿─━ _ ─━✧),防止后面多次搜索到该岛屿;若搜索到的“#”四周不全是“.”,则将该“#”换成“0”,表示已搜,以防多次搜索,紧接着调用find()函数将与之相连的“#”重复上述操作,直至确定该岛屿是否会被淹没。
代码实现:
import java.io.*;
import java.util.Stack;
public class Main {
static char[][] arr;
static int num = 0;
static void find(int x, int y) {
arr[x][y] = '0';
if (arr[x + 1][y] != '.' && arr[x - 1][y] != '.' && arr[x][y + 1] != '.' && arr[x][y - 1] != '.') {
num--;
change(x, y);
return;
}
if (arr[x + 1][y] == '#')
find(x + 1, y);
if (arr[x - 1][y] == '#')
find(x - 1, y);
if (arr[x][y + 1] == '#')
find(x, y + 1);
if (arr[x][y - 1] == '#')
find(x, y - 1);
}
static void change(int x, int y) {
Stack<Integer> stack = new Stack<>();
stack.add(x);
stack.add(y);
while (!stack.isEmpty()) {
y = stack.pop();
x = stack.pop();
arr[x][y] = '.';
if (arr[x + 1][y] != '.') {
stack.add(x + 1);
stack.add(y);
}
if (arr[x - 1][y] != '.') {
stack.add(x - 1);
stack.add(y);
}
if (arr[x][y + 1] != '.') {
stack.add(x);
stack.add(y + 1);
}
if (arr[x][y - 1] != '.') {
stack.add(x);
stack.add(y - 1);
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
arr = new char[n][n];
for (int i = 0; i < n; ++i) {
arr[i] = br.readLine().toCharArray();
}
for (int i = 1; i < n - 1; ++i) {
for (int j = 1; j < n - 1; ++j) {
if (arr[i][j] == '#') {
num++;
find(i, j);
}
}
}
System.out.println(num);
}
}