全球变暖 简单 DFS 蓝桥杯2018 省赛

给定一张表示海域的像素照片,其中陆地由#表示,海洋由.表示。题目要求模拟全球变暖导致的海平面上升,预测所有可能被完全淹没的岛屿。通过深度优先搜索(DFS)遍历并标记陆地,判断其是否会被淹没。程序读入照片大小和内容,输出将被完全淹没的岛屿数量。
摘要由CSDN通过智能技术生成

题目描述
你有一张某海域 NxNNxN 像素的照片,".“表示海洋、”#"表示陆地,如下所示:

.......

.##....

.##....

....##.

..####.

...###.

.......

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

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

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

.......

.......

.......

.......

....#..

.......

.......

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

输入描述

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

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

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

输出一个整数表示答案。

输入输出样例

示例
输入

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

输出

1

思路:
根据题意,只要是连接在一起的陆地就可以构成岛屿,实例就只有两块岛屿,只用看这两块岛屿中是不是有没有沉没的陆地就好了
沉没的定义是上下左右有海洋像素就可以了,所以先全部搜索了一遍,每一个陆地是否会沉没,再去用dfs搜索每一块岛屿,每一次dfs都把这次搜到的相连的陆地标为true,就保证了每次main里的dfs次数就是岛屿次数。
每次main都用一个ok来查这块岛屿是否有没沉没的陆地,有就把ok标成true,但还是要继续标剩下相连的陆地,因为它们是一块岛屿

#include <bits/stdc++.h>
using namespace std;
char mp[1005][1005];
bool vis[1005][1005];
bool is_on[1005][1005];  //是否在海上
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int n,ans;
bool ok;
//是否沉到海里
bool find(int x,int y){
    for (int i = 0; i < 4; i++) {
        int tx = x+dir[i][0];
        int ty = y+dir[i][1];
        if (mp[tx][ty]=='.') return true;
    }
    return false;
}
void dfs(int x,int y){
    if (vis[x][y] == true) return;
    vis[x][y] = true;
    if (is_on[x][y]) ok = true;
    for (int i = 0; i < 4; i++) {
        int tx = x+dir[i][0];
        int ty = y+dir[i][1];
        if (mp[tx][ty]=='#')dfs(tx,ty);
    }
}
int main(){
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> mp[i];
    }
    for (int i = 1; i < n-1; i++) {
        for (int j = 1; j < n-1; j++) {
            if (mp[i][j]=='#'){
                if (!find(i,j)) is_on[i][j] = true;
            }
        }
    }
    for (int i = 1; i < n-1; i++) {
        for (int j = 1; j < n-1; j++) {
            if (mp[i][j] == '#'&&vis[i][j]==false){
                ok = false;
                dfs(i,j);
                if (!ok) ans++;
            }
        }
    }
    cout << ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值