第九届蓝桥杯省赛JAVA——全球变暖

12 篇文章 0 订阅
9 篇文章 0 订阅

题目:


标题:全球变暖

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

.......
.##....
.##....
....##.
..####.
...###.
.......

其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。  

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

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

.......
.......
.......
.......
....#..
.......
.......

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

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

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

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

【输入样例】

.......
.##....
.##....
....##.
..####.
...###.
.......  

【输出样例】
1  

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


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

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

参考解释:https://blog.csdn.net/memeda1141/article/details/80232137比较详细。

参考原文:http://www.cnblogs.com/flightless/p/8718443.html 

思路: 

首先,我们要判断有多少个岛屿,那么可以用两个for进行遍历,遇到第一个'#'的时候,则为存在一个岛屿。

为了方便统计,我们可以把像素点分为可淹没点不可淹没点,如果像素点的"上下左右"四个方向上都是陆地‘#’,则是  不可淹没点,否则为可淹没点。

如题目所有样例:

.......
.##....
.##....
....##.
..####.
...###.
.......

若干年后:

.......
.......
.......
.......
....#..
.......
.......

我们可以看到,红色的‘#’上下左右都是‘#’,肯定是不可淹没的点。

求解: 



public class 全球变暖 {
	
	static char[][] map = new char[110][110];	//存储海域NxN像素
	static int[] ans = new int[11000];			//记录岛屿数量
	static boolean[][] vis = new boolean[110][110];	//像素访问标识,初始化所有的点都是  未被访问的
	
	static void dfs(int x, int y, int n,int k) {	//x:行,y:列,n:行列数,k:岛屿数目
		if(map[x][y]=='.')	//如果是海洋,不进行判断
			return;
		if(vis[x][y])		//如果当前像素已经被访问,跳过
			return;
		vis[x][y] = true;	//置为被访问状态
		if(x>=0 && x<n && y>=0 && y<n) 		//防止数组越界
			if(map[x-1][y]=='#' && map[x+1][y]=='#' && map[x][y-1]=='#' && map[x][y+1]=='#') 	//"上下左右"四个方向上都是陆地‘#’,则是  不可淹没点,否则为可淹没点
				ans[k]++;				//不可淹没点+1
			
		//进行四个方向dfs遍历
		dfs(x-1, y, n, k);
		dfs(x+1, y, n, k);
		dfs(x, y-1, n, k);
		dfs(x, y+1, n, k);
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		input.nextLine();			//记得换行输入
		for(int i=0; i<n; i++) {		//输入海域像素
			String pixel = input.nextLine();//照片保证第1行、第1列、第N行、第N列的像素都是海洋。 
			map[i] = pixel.toCharArray();
		}
		int len = 0;
		for(int i=0; i<n; i++) {	//注意:从这里判断其实就可以找出两个岛屿了,因为两个岛屿之间隔着海洋'.'
			for(int j=0; j<n; j++) {//第一个岛屿的陆地已经被访问完,接下来,先访问'.',,此时不进行搜索;再次遇到'#',才会进行dfs搜索,此时len++
				if(map[i][j]=='#' && !vis[i][j]) {//如果是陆地‘#’,且没有进行过访问,则进行寻找
					dfs(i, j, n, len);
					len++;				//岛屿数目加1
				}
			}
		}
		
		int sum = 0;
		for(int i=0; i<len; i++) {
		//	System.out.println(ans[i]);
			if(ans[i] == 0) {	//ans[i]=0说明该岛屿会被淹没,>0说明岛屿存在不可淹没点
				sum++;
			}
		}
		
		System.out.println(sum);
		
	}

}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值