2014. 岛

题目链接

acwing2014. 岛

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

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

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

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

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

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

image

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

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

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

输入格式

第一行包含整数 N

接下来 N 行,每行包含一个整数表示 Hi

输出格式

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

数据范围

1N105,
1Hi109

输入样例:

8 3 5 2 3 1 4 2 3

输出样例:

4

解题思路

枚举 思维

雨水只有在某个柱子的高度时才对答案有影响,所以可以枚举每个柱子的高度,对于相邻高度相等的柱子可以合并为一个柱子,即去重。然后由低到高枚举柱子高度,如果当前柱子位于低谷,则淹没该柱子后岛屿数会加一,位于顶峰则减一,另外需要注意边界的情况

  • 时间复杂度:O(nlogn)

代码

#include<bits/stdc++.h> using namespace std; int n; vector<int> a; vector<pair<int,int>> b; int main() { for(scanf("%d",&n);n;n--) { int x; scanf("%d",&x); a.push_back(x); } a.erase(unique(a.begin(),a.end()),a.end()); n=a.size(); for(int i=0;i<n;i++)b.emplace_back(a[i],i); sort(b.begin(),b.end()); int res=1,cnt=1; for(int i=0;i<n;i++) { int x=b[i].first,y=b[i].second; if(y==0) { if(y+1<n&&x>a[y+1])cnt--; } else if(y==n-1) { if(y-1>=0&&x>a[y-1])cnt--; } else if(x>a[y-1]&&x>a[y+1])cnt--; else if(x<a[y-1]&&x<a[y+1])cnt++; if(i==n-1||x!=b[i+1].first) res=max(res,cnt); } printf("%d",res); return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15836069.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示