有N个岛连在一起形成了一个大的岛屿,如果海平面上升超过某些岛的高度时,则这个岛会被淹没。原本的大岛屿则会分为多个小岛屿,如果海平面一直上升,则所有岛都会被淹没在水下。
给出N个岛的高度。然后有Q个查询,每个查询给出一个海平面的高度H,问当海平面高度达到H时,海上共有多少个岛屿。例如:
岛屿的高度为:{2, 1, 3, 2, 3}, 查询为:{0, 1, 3, 2}。
当海面高度为0时,所有的岛形成了1个岛屿。
当海面高度为1时,岛1会被淹没,总共有2个岛屿{2} {3, 2, 3}。
当海面高度为3时,所有岛都会被淹没,总共0个岛屿。
当海面高度为2时,岛0, 1, 3会被淹没,总共有2个岛屿{3} {3}。
收起
输入
第1行:2个数N, Q中间用空格分隔,其中N为岛的数量,Q为查询的数量(1 <= N, Q <= 50000)。 第2 - N + 1行,每行1个数,对应N个岛屿的高度(1 <= A[i] <= 10^9)。 第N + 2 - N + Q + 1行,每行一个数,对应查询的海平面高度(1 <= Q[i] <= 10^9)。
输出
输出共Q行,对应每个查询的岛屿数量。
输入样例
5 4 2 1 3 2 3 0 1 3 2
输出样例
1 2 0 2
思路:把序列按值从小到大排序,然后询问也这样排序,按照问题把小于它的值一个一个删除,每次删除只要判断他位置的左右两边的点是否删除即可,
代码:
#include<bits/stdc++.h>
using namespace std;
int sum[50009];
int vis[50009]={};
struct dao
{
int h;
int id;
}a[50009],b[50009];
const com(const dao &a,const dao &b)
{
return a.h<b.h;
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i].h);
a[i].id=i;
}
for(int i=0;i<q;i++)
{
scanf("%d",&b[i].h);
b[i].id=i;
}
sort(a,a+n,com);
sort(b,b+q,com);
int j=0;
int cnt=1;
for(int i=0;i<q;i++)
{
while(a[j].h<=b[i].h&&j<n)
{
if(a[j].id==0)
{
if(vis[a[j].id+1])
{
cnt--;
}
}
else if(a[j].id==n-1)
{
if(vis[a[j].id-1])
{
cnt--;
}
}
else
{
if(vis[a[j].id-1]&&vis[a[j].id+1])
{
cnt--;
}
else if(vis[a[j].id-1]==0&&vis[a[j].id+1]==0)
{
cnt++;
}
}
vis[a[j].id]=1;
j++;
}
sum[b[i].id]=cnt;
}
for(int i=0;i<q;i++)
{
cout<<sum[i]<<endl;
}
}