第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
思路:
1、暴力处理O(nm)肯定不行,那么考虑对其进行优化:
①首先我们对山峰的高度进行从小到大排序,当然我们同时留一个索引(输入的时候a【i】.pos=i)用来记录原来的位子。.
②然后我们对询问的水平线的高度进行从小到大排序,当然我们同事也留一个索引,用来记录原来的位子。
③对于当前询问的水平线高度,我们对应将比这个高度低的山峰高度全部置为0.(因为进行了排序,那么我们这里处理会非常方便)
④同时我们对这些山峰进行处理的时候处理两种情况:第一种就是多了一片岛屿,第二种就是少了一片岛屿,对应第一种情况,如果当前去掉的这个山峰的两边都是山峰,那么才能多一片岛屿,对于第二种情况,如果当前去掉的这个山峰的两边都是水了,我们才能少了一片岛屿。之前排序的时候我们保留了索引,所以这里的处理也是非常简单的。
⑤对应将所有询问都处理完毕之后,统一输出即可。
#include<bits/stdc++.h>
using namespace std;
struct node
{
int a,b;
} q[50005],p[50005];
int cmp(node x,node y)
{
return x.a<y.a;
}
int cmp1(node x,node y)
{
return x.b<y.b;
}
int main()
{
int m,n;
int temp[50005];
while(cin>>m>>n)
{
memset(temp,0,sizeof(temp));
for(int i=0; i<m; i++)
{
cin>>q[i].a;
q[i].b=i;
}
for(int i=0; i<n; i++)
{
cin>>p[i].a;
p[i].b=i;
}
sort(q,q+m,cmp);
sort(p,p+n,cmp);
int sum=1;
int j=0;
for(int i=0; i<n; i++)
{
while(q[j].a<=p[i].a&&j<m)
{
if(q[j].b==0)
{
if(temp[1]==1)
sum--;
}
if(q[j].b==m-1)
{
if(temp[m-2]==1)
sum--;
}
else
{
if(temp[q[j].b-1]==0&&temp[q[j].b+1]==0)
sum++;
if(temp[q[j].b-1]==1&&temp[q[j].b+1]==1)
sum--;
}
temp[q[j].b]=1;
j++;
}
p[i].a=sum;
}
sort(p,p+n,cmp1);
for(int i=0; i<n; i++)
cout<<p[i].a<<endl;
}
return 0;
}
思路:
1、暴力处理O(nm)肯定不行,那么考虑对其进行优化:
①首先我们对山峰的高度进行从小到大排序,当然我们同时留一个索引(输入的时候a【i】.pos=i)用来记录原来的位子。.
②然后我们对询问的水平线的高度进行从小到大排序,当然我们同事也留一个索引,用来记录原来的位子。
③对于当前询问的水平线高度,我们对应将比这个高度低的山峰高度全部置为0.(因为进行了排序,那么我们这里处理会非常方便)
④同时我们对这些山峰进行处理的时候处理两种情况:第一种就是多了一片岛屿,第二种就是少了一片岛屿,对应第一种情况,如果当前去掉的这个山峰的两边都是山峰,那么才能多一片岛屿,对于第二种情况,如果当前去掉的这个山峰的两边都是水了,我们才能少了一片岛屿。之前排序的时候我们保留了索引,所以这里的处理也是非常简单的。
⑤对应将所有询问都处理完毕之后,统一输出即可。
2、题目还是很有趣的~