岛
题目链接:https://www.acwing.com/problem/content/2016/
题解
首先,土地的高度过大,直接遍历会超时,需要找到规律:
- 当水平面在某个上涨范围内满足,没有土地处于这个范围内,水平面则在范围内上涨作用是等效的,所以可以直接遍历每个土地的高度。
- 考虑每个土地的左右相邻的第一个高度不同的土地,当左小右大和左大右小时,淹没该土地小岛数不发生变化。
当左小右小时,数量会减一,当左大右大时,数量会加一。(建议画图) - 如何找到左右相邻的第一个高度不同的土地?开始时将相邻且高度相同的土地进行去重操作。
代码
#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;
}