蓝桥杯【全球变暖】Java

全球变暖

你有一张某海域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);
	}

}

运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_50816725/article/details/109035701