题目链接:https://www.acwing.com/problem/content/2016/

题解

首先,土地的高度过大,直接遍历会超时,需要找到规律:

  1. 当水平面在某个上涨范围内满足,没有土地处于这个范围内,水平面则在范围内上涨作用是等效的,所以可以直接遍历每个土地的高度。
  2. 考虑每个土地的左右相邻的第一个高度不同的土地,当左小右大和左大右小时,淹没该土地小岛数不发生变化。
    当左小右小时,数量会减一,当左大右大时,数量会加一。(建议画图)
  3. 如何找到左右相邻的第一个高度不同的土地?开始时将相邻且高度相同的土地进行去重操作。

代码

#include 
#include 
#include 
using namespace std;
const int N = 1e5+10;
int n;
int h[N];
pair p[N]; 
int main()
{
    cin >> n;
    for (int i = 1 ; i <= n ; i ++ ) cin >> h[i];
    
    n = unique(h+1,h+1+n) - h - 1;
    h[n+1] = 0;
    
    for (int i = 1 ; i <= n ; i ++ ) p[i] = {h[i],i};
    
    sort(p+1,p+n+1);
    
    int cnt = 1;
    int ans = 0;
    for (int i = 1; i <= n; i ++ ) {
        int u = p[i].second;
        if(h[u] < h[u - 1] && h[u] < h[u + 1]) cnt ++ ;
        else if(h[u] > h[u - 1] && h[u] > h[u + 1]) cnt -- ;
        // 将同一高度的处理完再取最值,防止两个相同高度的在同一片岛上,影响答案
        if(p[i].first != p[i+1].first) ans = max(ans,cnt);
    }
    cout << ans << endl;
    return 0;
}