蓝桥杯 18省赛 B9 全球变暖(队列)

蓝桥杯 18省赛 B9 全球变暖(队列)

标题:全球变暖

你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:
在这里插入图片描述

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

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

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

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

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

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

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

【输入样例】
7

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

【输出样例】
1

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

======================

思路:
先得到海水蔓延之后没有沉没的陆地索引
再遍历这些未沉没的陆地索引,得出这些陆地索引一共组成多少个岛屿
为了使扫描(遍历)的范围尽量的小,我使用队列作为遍历容器

public class 全球变暖_dfs_9 {
	static int n;
	static char[] a;
	static Queue<Integer> q =new LinkedList<Integer>();
	public static void main(String[] args) {
		init();
		
		int[] oper = {-1 ,1 ,-n ,n};		//操作数组,遍历四周的索引
		int tmp =0 ,index =q.size();		//为什么使用index变量:这使得我后面可以继续往队列添加元素,却不影响我退出循环的判断
		while(true) {
			if(index -- ==0) break;
			tmp =q.poll();
			boolean isOcc =false;			//四周是否有海洋
			for(int o :oper) if(a[tmp +o] =='.') {isOcc =true; break;}
			if(!isOcc) q.add(tmp);			//四周均是地面
		}
		
		int ans =0;
		while(true) {
			if(q.size() ==0) break;
			tmp =q.poll();
			boolean isFlag =false;			//四周是否有被遍历过(标记)的地面
			for(int o :oper) if(a[tmp +o] =='+') {isFlag =true; break;}
			a[tmp] ='+';					//遍历地面之后,使其标记
			if(!isFlag) ans ++;
		}
		System.out.println(ans);
	}
	private static void init() {
		Scanner sc = new Scanner(System.in);
		n =sc.nextInt();
		a =new char[n *n];
		char[] tmp;
		for(int i =0 ;i <n ;i ++) {
			tmp =sc.next().toCharArray();
			for(int j =0 ;j <n ;j ++) {
				a[i *n +j] =tmp[j];
				if(tmp[j] =='#') q.add(i *n +j);
			}
		}
		sc.close();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肯尼思布赖恩埃德蒙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值