第九届蓝桥杯Java B组第九题全球变暖题解

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

标题:全球变暖

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

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

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

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

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

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

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

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

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

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

7
.......
.##....
.##....
....##.
..####.
...###.
.......  

【输出样例】

1

主要思路为利用深搜计算初始的岛屿数目以及融化后的岛屿数目,两者相减,若小于0,则变为0,若大于0,则直接输出

Java代码如下:

import java.util.Scanner;

public class CalculateIsland {
    
    static int N;
    //vis数组表示某个点是否走过
    static int[][] vis;
    //dir数组代表上下左右四个方向
    static int[][] dir = {{-1,0},{1,0},{0,-1},{0,1}};
    
    //深搜遍历
    static void dfs(char[][] a,int x,int y) {
        for (int i=0;i<4;i++) {
            int dx = x + dir[i][0];
            int dy = y + dir[i][1];
            //判断条件
            if(dx>=0 && dx<N && dy>=0 && dy<N && vis[dx][dy]==0 && a[dx][dy]=='#') {
                vis[dx][dy] = 1;
                dfs(a,dx,dy);
            }
        }
    }
    
    //计算岛屿的数量
    static int IslandCount(char[][] a) {
        int count = 0;
        for (int i=0;i<N;i++) {
            for(int j=0;j<N;j++) {
                if(a[i][j]=='#' && vis[i][j]==0) {
                    vis[i][j] = 1;
                    dfs(a,i,j);
                    count++;
                }
            }
        }
        return count;
    }

    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        //此处注意换行
        sc.nextLine();
        //代表初始化的N*N数组
        char[][] a = new char[N][N];
        //代表融化后的情况
        char[][] result = new char[N][N];
        //初始化
        vis = new int[N][N];
        String s;
        for (int i=0;i<N;i++) {
            s = sc.nextLine();
            a[i] = s.toCharArray();
        }
        //复制数组a,使得result和a一样
        for (int i=0;i<N;i++) {
            System.arraycopy(a[i], 0, result[i], 0, a[0].length);
        }
        //count代表数组a初始的岛屿数量
        int count = IslandCount(a);
        for (int i=0;i<N;i++) {
            for (int j=0;j<N;j++) {
                //如果该点初始为'#'
                if(a[i][j]=='#') {
                    int dx,dy;
                    for (int k=0;k<4;k++) {
                        dx = i + dir[k][0];
                        dy = j + dir[k][1];
                        //越界
                        if(dx<0 || dx>=N || dy<0 || dy>=N ) {
                            result[i][j] = '.';
                            break;
                        /**该点初始为'#',*/
                        /**初始位置若该点上下左右四个方向有'.'**/
                        /**则改点也变为'.'*/
                        }else if (a[dx][dy] == '.') {
                            result[i][j] = '.';
                            break;
                        }
                    }
                }
            }
        }
        //必须要重新初始化,
        //因为计算ans值还需要用到函数IslandCount().
        vis = new int[N][N];
        long ans = count - IslandCount(result);
        //可能会出现岛屿数目不变或者变多的情况,
        //这里进行判断处理
        if(ans <= 0) {
            ans = 0;
        }
        System.out.println(ans);
    }
}

运行结果

1.正常情况下岛屿数变少的情况

2.岛屿融化后变多的情况

好了,这次的题解就到这儿了,大家有什么问题可以在评论区留言!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值