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

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

约翰的田地被描述为由 岛(寒假每日一题 5)_i++ 个连续高度值 岛(寒假每日一题 5)_i++_02 指定的一维场景。

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

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

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

岛(寒假每日一题 5)_离散化_03

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

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

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

输入格式
第一行包含整数 岛(寒假每日一题 5)_i++

接下来 岛(寒假每日一题 5)_i++ 行,每行包含一个整数表示 岛(寒假每日一题 5)_c++_06

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

数据范围
岛(寒假每日一题 5)_离散化_07

输入样例:

8
3
5
2
3
1
4
2
3

输出样例:

4


解法一

  1. 对相邻的高度相同的柱子去重,做成一个 pair<int,int> 数组 分别记录高度和对应的下标
  2. 按高度升序排列,然后进行遍历,对同一高度的柱子逐渐消去
  3. 消去时,如果当前柱子两边没淹没,则 cnt++,如果两边有一个淹没,则 cnt 不变,如果两边都被淹没则 cnt–(默认两边边界高度为0)
  4. 最后输出遍历过程中的 max(cnt) 即可(同一高度处理完才能取一次 max)
#include<iostream>
#include<vector>
#include<algorithm>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 100010;

PII q[N];
int h[N];

int main(){

int n;

scanf("%d", &n);

for(int i = 1; i <= n; i++) scanf("%d", &h[i]);

n = unique(h + 1, h + n + 1) - h - 1; // 判重
h[n + 1] = 0; // n + 1出高度默认为0

for(int i = 1; i <= n; i++) q[i] = {h[i], i};

sort(q + 1, q + n + 1);

int cnt = 1, res = 1;
for(int i = 1; i <= n; i++){

int k = q[i].y;

if(h[k - 1] < h[k] && h[k + 1] < h[k]) cnt--;
else if(h[k - 1] > h[k] && h[k + 1] > h[k]) cnt++;

if(q[i].x != q[i + 1].x) res = max(res, cnt);
}

cout << res << endl;

return 0;
}

解法二

  1. 对相邻的高度相同的柱子去重,做成一个 pair<int,int> 数组 分别记录高度和对应的下标
  2. 按高度升序排列,然后进行遍历,对同一高度的柱子逐渐消去
  3. 用一个 bool 数组来表示当前柱子是否被淹没
  4. 消去时,如果当前柱子两边没淹没,则 cnt++,如果两边有一个,则 cnt 不变,如果两边都没有则 cnt-- (默认两边已经被淹没(0和n+1))
  5. 最后输出 遍历过程中的 max(cnt) 即可(同一高度处理完才能取一次 max)
#include<iostream>
#include<vector>
#include<algorithm>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 100010;

PII q[N];
bool st[N];
int h[N];

int main(){

int n;

scanf("%d", &n);


for(int i = 1; i <= n; i++) scanf("%d", &h[i]);

n = unique(h + 1, h + n + 1) - h - 1;

for(int i = 1; i <= n; i++) q[i] = {h[i], i};

sort(q + 1, q + n + 1);

int cnt = 1, res = 1;
st[0] = true, st[n + 1] = true;
for(int i = 1; i <= n; i++){

int idx = q[i].y;

st[idx] = true;

int l = idx - 1, r = idx + 1;

if(st[l] && st[r]) cnt--;
else if(!st[l] && !st[r]) cnt++;

if(i == n || q[i].x != q[i+1].x) res = max(res, cnt);
}

cout << res << endl;

return 0;
}