蓝桥杯 全球变暖

题目描述

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

.......

.##....

.##....

....##.

..####.

...###.

.......

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

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

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

.......

.......

.......

.......

....#..

.......

.......

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

输入描述

第一行包含一个整数 N (1≤N≤1000)。

以下 N 行 N 列代表一张海域照片。

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

输出一个整数表示答案。

输入输出样例

7

.......

.##....

.##....

....##.

..####.

...###.

.......

输出

1

这是一道基本连通性问题。算法的方案就是遍历一个连通块,找到这个连通块中所有的#,并标记为搜过,以后不再搜索。接下来在遍历下一个连通块,直到遍历完所有连通块,统计有多少个连通块。

用暴力搜索解决连通性问题,逐个搜索连通块上的所有点,每个点只搜索一次,实现这种简单的暴力搜索,BFS和DFS都可以,不仅很容易搜索到所有点,而且每个点只搜索一次。

什么岛屿不会被完全淹没呢?若岛中有一块地(高地),它周围都是陆地,那么这个岛屿不会被淹没。用DFS或者BFS搜索出有多少个岛(连通块),检查这个岛有没有高地,统计那些没有高地的岛屿数量就是答案。

DFS搜索所有点,若遇到#,就继续搜索它周围的#。把搜索过的#标记为已经搜索过,不用再搜索,统计那些没有高地的岛的数量,就是答案。搜索的时候应该判断是不是出了边界。照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。那么就不用判断边界了,到了边界,发现是水,会停止搜索。

import java.util.Scanner;

public class mian1 {
    static int N=1001;
    static int visit[][]=new int[N][N];
    static int dir[][]=new int[][] {{-1,0},{1,0},{0,-1},{0,1}};
    static int flag=0;
    static void dfs(char map[][],int x,int y) {
        visit[x][y]=1;//走过
        if(map[x][y+1]=='#'&&map[x][y-1]=='#'&&map[x+1][y]=='#'&&map[x-1][y]=='#') {
            flag=1;
        }
        for (int i = 0; i < 4 ; i++) {
            int nx=x+dir[i][0];
            int ny=y+dir[i][1];
            if(visit[nx][ny]==0&&map[nx][ny]=='#') {
                dfs(map,nx,ny);
            }
        }
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        int num=sc.nextInt();
        char map[][]=new char[num][num];
        for (int i = 0; i < num; i++) {
            map[i]=(sc.next()).toCharArray();
        }
        int ans=0;
        for (int i = 1; i < num-1; i++) {
            for (int j = 1; j < num-1; j++) {
                if(visit[i][j]==0&&map[i][j]=='#') {
                    flag=0;
                    dfs(map,i,j);
                    if(flag==0) {
                        ans++;
                    }
                }
            }
        }
        System.out.println(ans);
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值