第九届 蓝桥杯 JavaB组 全球变暖

标题:全球变暖

你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:


.##…
.##…
…##.
…####.
…###.

其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

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




…#…

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

【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。

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

【输出格式】
一个整数表示答案。

【输入样例】
7

.##…
.##…
…##.
…####.
…###.

【输出样例】
1

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。

方法:
三步
第一步:用dfs找出总共的岛屿数目
第二步:用两个for循环淹没岛屿(注意理解题意,四面一面邻海就要被淹没,但是程序运行时一次淹没一个岛屿,所以我们需要用一个vis数组来表示这个岛屿是被淹没的岛屿还是从最开始就是海洋)
第三步:再用dfs找出淹没后还有多少个岛屿,前后相减就是被淹没的岛屿数

package 第九届;

import java.util.Scanner;

public class _09全球变暖 {
	static int n;
	static int[][] dfs_vis; 
	static int dir[][] = {{1,0},{-1,0},{0,1},{0,-1}};
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		sc.nextLine();
		dfs_vis = new int[n][n];
		char[][] map = new char[n][n];
		for(int i = 0; i < n; i++) {
				String s = sc.nextLine();
				map[i] = s.toCharArray();
		}
		//找岛屿
		int start = 0;
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				if(map[i][j] == '#' && dfs_vis[i][j] == 0) {
					dfs_vis[i][j] = 1;
					dfs(i,j,map);
					start++;
				}
			}
		}
		
		//淹没
		int vis[][] = new int[n][n];
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				if(map[i][j] == '#') {
					vis[i][j] = 1;
					for(int k = 0; k < 4; k++) {
						int nx = i + dir[k][0];
						int ny = j + dir[k][1];
						if(check(nx,ny,n) && map[nx][ny] == '.' && vis[nx][ny] == 0) {
							//vis[nx][ny] = 1;
							map[i][j] = '.';
							break;
						}
					}
				}
			}
		}
		
		//找淹没后剩余的岛屿
		dfs_vis = new int[n][n];
		int end = 0;
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				if(map[i][j] == '#' && dfs_vis[i][j] == 0) {
					dfs_vis[i][j] = 1;
					dfs(i,j,map);
					end++;
				}
			}
		}
		
		System.out.println(start);
		System.out.println(end);
		System.out.println(start-end);
	}
	
	private static void dfs(int i, int j, char[][] map) {
		for(int k = 0; k < 4; k++) {
			int nx = i + dir[k][0];
			int ny = j + dir[k][1];
			if(check(nx,ny,map.length) && map[nx][ny] == '#' && dfs_vis[nx][ny] == 0) {
				dfs_vis[nx][ny] = 1;
				dfs(nx,ny,map);
			}
		}
	}
	
	private static boolean check(int nx, int ny,int n) {
		
		return nx>=0 && nx<n && ny>=0 && ny<n;
	}

}

上一篇:@蓝桥杯javaB组习题集入门(4)第三题:圆的面积


下一篇:蓝桥杯JavaB--特别数的和