目录:算法日记
原题链接:2014. 岛 - AcWing题库
题目描述
每当下雨时,农夫约翰的田地总是被洪水淹没。
由于田地不是完全水平的,所以一些地方充满水后,留下了许多被水隔开的“岛”。
约翰的田地被描述为由 个连续高度值 指定的一维场景。
假设该场景被无限高的围墙包围着,请考虑暴雨期间发生的情况:
最低处首先被水覆盖,形成一些不连贯的岛,随着水位的不断上升,这些岛最终都会被覆盖。
一旦水位等于一块田地的高度,那块田地就被认为位于水下。
上图显示了一个示例:在左图中,我们只加入了刚好超过 单位的水,此时剩下 个岛(最大岛屿剩余数量),而在右图中,我们共加入了 单位的水,此时仅剩下 个岛。
请计算,暴风雨期间我们能在某个时间点看到的最大岛屿数量。
水会一直上升到所有田地都在水下。
输入格式
第一行包含整数 。
接下来 行,每行包含一个整数表示 。
输出格式
输出暴风雨期间我们能在某个时间点看到的最大岛屿数量。
数据范围
输入样例
8
3
5
2
3
1
4
2
3
输出样例
4
算法思路
如上图所示,对第个田地,表示该田地的高度。对任意一个岛屿,必定存在最高点,使得两边田地的高度均小于。因此,对一个岛屿的表示仅需考虑岛屿的上升段或下降段。规定岛屿以上升段表示。
设水位高度为,根据题意当时,第个田地成为了一个岛屿。
考虑边界情况
- 当时,第个田地仍是一个岛屿;
- 当时,第个田地被淹没;
当水位高度满足,第个田地就会使得岛屿数量增加,即对第个田地,仅在,岛屿数量才会增加,当岛屿消失,岛屿数量减少,符合差分形式。统计不同对应的岛屿数量,取最大值即为答案。
注意数据范围,需要使用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;
}