題意:直接看題意即可
題解:首先可以通過二分枚舉區間大小,然後通過單調隊列求出每個區間的最大值和最小值進行比較,最後得出答案即可。
附上代碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int maxd=1e6+5;
int n,d;
int deq[maxn],mx[maxn],mn[maxn];
int ans=0;
struct point{
int x,y;
};
point points[maxn];
bool cmp(point a,point b)
{
return a.x<b.x;
}
bool cal(int len)
{
ans=0;
int s=0,t=0;
for(int i=0;i<n;i++){
while(s<t&&points[deq[t-1]].y<=points[i].y){
t--;
}
deq[t++]=i;
while(points[i].x-points[deq[s]].x>len){
s++;
}
mx[i]=points[deq[s]].y;
}
s=t=0;
for(int i=0;i<n;i++){
while(s<t&&points[deq[t-1]].y>=points[i].y){
t--;
}
deq[t++]=i;
while(points[i].x-points[deq[s]].x>len){
s++;
}
mn[i]=points[deq[s]].y;
}
// cout<<len<<" "<<endl;
// for(int i=0;i<n;i++){
// cout<<mx[i]<<" ";
// }
// cout<<endl;
// for(int i=0;i<n;i++){
// cout<<mn[i]<<" ";
// }
// cout<<endl;
for(int i=0;i<n;i++){
ans=max(ans,mx[i]-mn[i]);
}
if(ans>=d){
return true;
}else{
return false;
}
}
int main()
{
scanf("%d%d",&n,&d);
for(int i=0;i<n;i++){
point &e=points[i];
scanf("%d%d",&e.x,&e.y);
}
sort(points,points+n,cmp);
int lb=-1,ub=maxd;
while(ub-lb>1){
int mid=(lb+ub)>>1;
if(cal(mid)){
ub=mid;
}else{
lb=mid;
}
}
if(ub>1e6){
printf("%d\n",-1);
}else{
printf("%d\n",ub);
}
return 0;
}