全球变暖

全球变暖

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

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

由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。

具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

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

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

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

输入格式

第一行包含一个整数N。

以下 N 行 N 列,包含一个由字符”#”和”.”构成的 N×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。

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

输出格式

一个整数表示答案。

数据范围

≤ ≤ 1000

输入样例1:

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

输出样例1:

1

输入样例2:

9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........

输出样例2:

1


第一次的思路就是三次DFS,(1)搜索出多少个岛屿,(2)把所有周边有海洋的陆地变成海洋,(3)再搜索有多少个陆地,最后的答案就是两次搜索的数差;
  但是忽略了一种情况,就是把海洋变成陆地时,有可能就是把之前一个岛屿变成了两个岛屿!
列如:
.........          .........
.##.##...      .........
.#####...      ..#.#....
.##.##...    .........
.........  -->    .........
.##.#....       .........
.#.###...      ....#....
.#..#....      .........
.........      .........
所以又想到,找到一片陆地时,搜索其他挨着的陆地,每找到一个就是cnt++,
若是这些陆地还挨着海洋就有cnt1++,最后搜索结束时,若是cnt == cnt1,便可以说明这个岛屿会被完全淹没。
#include <stdio.h>
#include <string.h>
int flag = 0, n, m, cnt = 0, cnt1 = 0, ans = 0;
int book[1005][1005];
char a[1005][1005], b[1005][1005];
int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};

void dfs(int x, int y) {
    if(x < 0 || y < 0 || x >= n || y >= n)return;
    if(a[x][y] != '#')return;
    if(book[x][y] == 1)return;
    book[x][y] = 1;
    cnt++;
    int i, j, tx, ty;
    for(i = 0; i < 4; i++) {
        tx = x + next[i][0];
        ty = y + next[i][1];
        dfs(tx,ty);
    }
    if(a[x][y] == '#') {
        for(i = 0; i < 4; i++) {
            tx = x + next[i][0];
            ty = y + next[i][1];
            if(tx < 0 || ty < 0 || tx >= n || ty >= n)continue;
            if(b[tx][ty] == '.') {//注意这里要和b数组比较
                flag = 1;
                break;
            }
        }
        if(flag == 1) {
            cnt1++;
        }
        flag = 0;
    }
}
int main() {
    int i, j, k, l;
    char d;
    scanf("%d",&n);
    getchar();//吃个回车很重要
    for(i = 0; i < n; i++) {
        for(j = 0; j <= n; j++) {//要小于等于n,这样a[i][n]就是等于'\0';也是相当于吃个回车
            scanf("%c",&d);
            a[i][j] = d;
            b[i][j] = d;
        }
    }
    for(i = 0; i < n; i++) {
        for(j = 0; j < n; j++) {
            if(a[i][j] == '#') {
                dfs(i,j);
                if(cnt == cnt1 && cnt != 0) {
                    ans++;
                }
                cnt = cnt1 = 0;
            }
        }
    }

    printf("%d\n",ans);
    return 0;
}

 






posted @ 2021-03-31 17:46  荣荣荣荣荣荣  阅读(57)  评论(0)    收藏  举报