AcWing 2014. 岛

160 阅读2分钟

目录:算法日记

原题链接:2014. 岛 - AcWing题库

题目描述

每当下雨时,农夫约翰的田地总是被洪水淹没。

由于田地不是完全水平的,所以一些地方充满水后,留下了许多被水隔开的“岛”。

约翰的田地被描述为由 NN 个连续高度值 H1,,HNH_1,…,H_N 指定的一维场景。

假设该场景被无限高的围墙包围着,请考虑暴雨期间发生的情况:

最低处首先被水覆盖,形成一些不连贯的岛,随着水位的不断上升,这些岛最终都会被覆盖。

一旦水位等于一块田地的高度,那块田地就被认为位于水下。

19_8c986a0cb5-fig_islands.png

上图显示了一个示例:在左图中,我们只加入了刚好超过 11 单位的水,此时剩下 44 个岛(最大岛屿剩余数量),而在右图中,我们共加入了 77 单位的水,此时仅剩下 22 个岛。

请计算,暴风雨期间我们能在某个时间点看到的最大岛屿数量。

水会一直上升到所有田地都在水下。

输入格式

第一行包含整数 NN

接下来 NN 行,每行包含一个整数表示 HiH_i

输出格式

输出暴风雨期间我们能在某个时间点看到的最大岛屿数量。

数据范围

  • 1N1051≤N≤10^5
  • 1Hi1091≤H_i≤10^9

输入样例

8
3
5
2
3
1
4
2
3

输出样例

4

算法思路

QQ截图20220109220407.png

如上图所示,对第ii个田地,HiH_i表示该田地的高度。对任意一个岛屿,必定存在最高点HtH_t,使得HtH_t两边田地的高度均小于HtH_t。因此,对一个岛屿的表示仅需考虑岛屿的上升段或下降段。规定岛屿以上升段表示。

设水位高度为hh,根据题意当Hi1hHiH_{i-1}≤h<H_i时,第ii个田地成为了一个岛屿。

考虑边界情况

  • hHi1h≤H_{i-1}时,第ii个田地仍是一个岛屿;
  • hHih>H_i时,第ii个田地被淹没;

当水位高度hh满足Hi1hHiH_{i-1}≤h<H_i,第ii个田地就会使得岛屿数量增加11,即对第ii个田地,仅在Hi1hH_{i-1}≤h,岛屿数量才会增加11,当hHih>H_i岛屿消失,岛屿数量减少11,符合差分形式。统计不同hh对应的岛屿数量,取最大值即为答案。

注意数据范围1Hi1091≤H_i≤10^9,需要使用map进行离散化。

AC代码

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int N = 1e5+10;
int h[N];
map<int, int> b;
int n;
int main() {
    cin>>n;
    for(int i = 1; i <= n; ++i) {
        cin>>h[i];
        if(h[i] > h[i-1]) {
            b[h[i-1]] += 1;
            b[h[i]] -= 1;
        }
    }
    int sum = 0;
    int res = 0;
    for(auto item : b) {
        sum += item.second;
        res = max(res, sum);
    }
    cout<<res<<endl;
    return 0;
}