全球变暖【蓝桥杯】【算法设计与分析】【BFS】

全球变暖【蓝桥杯】【算法设计与分析】【BFS】

问题描述:

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


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

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





…#…

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

解题算法思路:

  • 用bfs(不会重复)遍历一片连续的陆地,判断靠海的陆地个数和总陆地的个数的关系:如果靠海的陆地个数等于总陆地个数,则该岛屿会消失;否则不会消失。此处只有等于和小于的情况,没有大于的情况。

源代码

1.import java.io.IOException;  
2.import java.util.LinkedList;  
3.import java.util.Queue;  
4.import java.util.Scanner;  
5.  
6.public class globalWarming {//全球变暖  广度优先遍历  
7.    public static Queue<Point> queue = new LinkedList<Point>();  
8.    public static char area[][] = new char[1000+1][1000+1];//存放整个图片像素  
9.    public static int vis[][] = new int[1000+1][1000+1];//该陆地是否访问过  
10.    public static class Point{  
11.        int x,y;  
12.        public Point(int x,int y) {  
13.            this.x=x;  
14.            this.y=y;  
15.        }  
16.    }  
17.    public static boolean check(int x,int y) {//检查陆地是否靠海  
18.        if(area[x-1][y]=='.'||area[x+1][y]=='.'  
19.                ||area[x][y-1]=='.'||area[x][y+1]=='.')  
20.            return true;  
21.        return false;  
22.    }  
23.  
24.    public static boolean bfs(int x,int y) {//广度优先遍历不会重复  
25.        queue.offer(new Point(x, y));//将没访问过的陆地放入队列中  
26.        vis[x][y]=1;//设为已访问  
27.        int sea=0,land=0;//sea靠海的陆地个数,land陆地总数  
28.        int next[][] = {{-1,0},{1,0},{0,-1},{0,1}};//上下左右  
29.        while(!queue.isEmpty()) {  
30.            Point p =queue.poll();//取出队列第一个元素  
31.            land++;  
32.            if(check(p.x,p. y)) {  
33.                sea++;  
34.            }  
35.            for(int i=0;i<4;i++) {//遍历该陆地上下左右的区域,如果有未访问过的邻接点,则存入队列中  
36.                int r =p.x+next[i][0];  
37.                int c =p.y+next[i][1];  
38.                if(area[r][c]=='#'&&vis[r][c]==0) {  
39.                    queue.offer(new Point(r, c));  
40.                    vis[r][c]=1;  
41.                }  
42.            }  
43.        }  
44.        if(sea==land)return true;//靠海的陆地个数=陆地总数,则会被淹没  
45.        return false;  
46.    }  
47.  
48.    public static void main() throws IOException {  
49.        
50.        Scanner sc =new Scanner(System.in);  
51.        int n=sc.nextInt();  
52.        int num=0;//存放消失的岛屿数  
53.        for(int i=1;i<=n;i++) {  
54.            String str = sc.next();  
55.            char c[] = str.toCharArray();//一行字符串读入并转为字符数组  
56.            for(int j=1;j<=n;j++) {  
57.                area[i][j]=c[j-1];//第i行字符数组依次存入二维数组第i行  
58.            }  
59.        }  
60.        for(int i=1;i<=n;i++) {  
61.            for(int j=1;j<=n;j++) {  
62.                if(area[i][j]=='#'&&vis[i][j]==0) {//这是一块没访问过的陆地  
63.                    if(bfs(i,j)) {//如果靠海的陆地数等于陆地总数,则该岛屿会消失  
64.                        num++;  
65.                    }  
66.                }  
67.            }  
68.        }  
69.        System.out.println("照片中有"+num+"座岛屿会被完全淹没");  
70.        UI.main();  
71.    }  
72.  
73.}  

算法效率分析:

  • 由于使用的是广度优先遍历,它有一个特点就是不会重复,只要一遍历到正确答案就会返回。所以效率也还算可以,时间复杂度应该是O(n)

本文仅是萌新学习算法的一篇笔记,如有问题欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值