正题
这题看上去摸不着头脑,但是想想最大减最小,我们就会知道用两个单调队列来维护。
首先维护一个最大值的单调队列和最小值的单调队列,然后令当前最大值和最小值相减,看一下是否大于等于d,如果是,那么就记录答案,并不断把l向前移,直到最大值减最小值小于d时。
就是这样。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,d;
struct node{
int x,y;
bool operator<(const node a)const{
return x<a.x;
}
}s[100010];
node list1[100010],list2[100010];//list1维护当前区间最小值,list2维护当前区间最大值
int h1=0,h2=0;
int t1=1,t2=1;
int l=1;
int ans=1e9;
int main(){
scanf("%d %d",&n,&d);
for(int i=1;i<=n;i++)
scanf("%d %d",&s[i].x,&s[i].y);
sort(s+1,s+1+n);
for(int i=1;i<=n;i++){
int t=i;
while(h1>=t1 && list1[h1].y>s[i].y) h1--;list1[++h1]=s[i];
while(h2>=t2 && list2[h2].y<s[i].y) h2--;list2[++h2]=s[i];
while(list2[t2].y-list1[t1].y>=d && t1<=h1 && t2<=h2){
ans=min(ans,s[i].x-s[l].x);
if(list1[t1].x==s[l].x) t1++;
if(list2[t2].x==s[l].x) t2++;
l++;
}
}
if(ans==1e9) printf("-1");
else printf("%d",ans);
}
本文介绍如何使用两个单调队列求解给定数组中满足条件的最大值与最小值之差大于等于d的最短区间长度。通过不断更新队列来维护区间内的最大值与最小值,并调整窗口大小直至找到满足条件的最短区间。
473

被折叠的 条评论
为什么被折叠?



