蓝桥杯 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();
}
}