题目
每当下雨时,农夫约翰的田地总是被洪水淹没。
由于田地不是完全水平的,所以一些地方充满水后,留下了许多被水隔开的“岛”。
约翰的田地被描述为由 N
个连续高度值 H1,…,HN
指定的一维场景。
假设该场景被无限高的围墙包围着,请考虑暴雨期间发生的情况:
最低处首先被水覆盖,形成一些不连贯的岛,随着水位的不断上升,这些岛最终都会被覆盖。
一旦水位等于一块田地的高度,那块田地就被认为位于水下。
上图显示了一个示例:在左图中,我们只加入了刚好超过 1 单位的水,此时剩下 4 个岛(最大岛屿剩余数量),而在右图中,我们共加入了 7 单位的水,此时仅剩下 2 个岛。
请计算,暴风雨期间我们能在某个时间点看到的最大岛屿数量。
水会一直上升到所有田地都在水下。
输入格式
第一行包含整数 N。
接下来 N 行,每行包含一个整数表示 Hi。
输出格式
输出暴风雨期间我们能在某个时间点看到的最大岛屿数量。
数据范围
1≤N≤105,
1≤Hi≤109
输入样例:
8
3
5
2
3
1
4
2
3
输出样例:
4
题解说明
思路
随着水位的上升,岛会根据岛高度由低到高的顺序逐一被水面覆盖,所以这里用贪心(枚举)方法对岛由低到高的进行枚举,枚举过程中对仍在水面上的岛的数量进行变动。
PS:
①对于水面每覆盖一个岛,一共有四种情况:
可以发现:只有当出现“中间高两侧低”状态时,岛屿数减1
,当出现“中间低两侧高”时,岛屿数加1
,其他情况岛屿数均不变。
代码
#include<iostream>
#include<cstring>
#include<algorithm>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 100010;
int n;
int h[N];//记录每座山的高度,用于枚举每个q时与相邻h对比
PII q[N];//q用于高度排序后枚举
int main(){
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;
//printf("n=%d\n",n);
for(int i = 1; i <= n; i ++) q[i] = {
h[i], i}; //将【每座岛的高度,下表序号】存入q
sort(q + 1, q + n + 1);//排序
int res = 1;//定义答案
int cnt = 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);
}
printf("%d\n", res);
return 0;
}
希望可以帮到你,欢迎点赞评论哦