题目传送门:https://www.acwing.com/problem/content/2016/
题目大意:中文题面
解题思路:数据范围是1e5,所以,我们完全可以按从低到高枚举每一个平地的高度去加水,然后计算岛的数量。
当然计算岛的数量不能再枚举啦,肯定会超时的。其实只用看两旁的平地高度就行,若两旁都比较高,则岛数量加一,若只有一旁高,则数量不变,若两边都低,则数量减一。(注意两个边界不一样,不过只需要将数组0和n+1预处理成高的一旁就行)。
代码如下:
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<cstring>
using namespace std;
#define ll long long
const int maxn = 100000 + 500;
const int inf = 1e9 + 7;
struct node{
int num,high;
};
node a[maxn];
bool cmp(node w,node e){
if(w.high<=e.high)return true;
return false;
}
int vis[maxn];//标记该位置是否被淹没
int main() {
int n;
cin>>n;
for(int i=1;i<=n;i++){
a[i].num=i;
cin>>a[i].high;
}
sort(a+1,a+n+1,cmp);
vis[0]=1,vis[n+1]=1;//边界被岛数不增加,故先将边界旁边的vis标记为1
//for(int i=1;i<=n;i++)cout<< a[i].num<<' '<<a[i].high<<endl;
int sum=1;//岛的总数
int maxsum=0;//最大的岛数
for(int i=1;;){
if(!vis[a[i].num-1]&&!vis[a[i].num+1])sum++;
else if(vis[a[i].num-1]&&vis[a[i].num+1])sum--;
vis[a[i].num]=1;
for(int j=i+1;j<=n+1;j++){
if(a[i].high==a[j].high){
if(!vis[a[j].num-1]&&!vis[a[j].num+1])sum++;
else if(vis[a[j].num-1]&&vis[a[j].num+1])sum--;
vis[a[j].num]=1;
}
else {i+=j-i;break;}
}
//cout<<sum<<endl;
if(maxsum<sum)maxsum=sum;
if(i>=n)break;
}
cout<<maxsum;
return 0;
}