P2698 [USACO12MAR]Flowerpot S 题解
本题题意简单明了。
首先,题目当中 最小 二字,就是在提示我们使用二分。
然后,要求最大值与最小值的差,并且区间长度固定,各位能想到什么?我想到的是使用单调队列维护。
做法:
- 首先对输入数组按照 \(x\) 坐标升序排序。
- 然后二分花盆长度,跑一次单调队列即可。
所以结束了?代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int n,d;
struct node
{
int x,y;
}a[MAXN];
int read()
{
int fh=1,sum=0;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
sum=(sum<<3)+(sum<<1)+ch-'0';
ch=getchar();
}
return sum*fh;
}
bool cmp(const node &fir,const node &sec)
{
return fir.x<sec.x;
}
bool check(int k)
{
deque<int>qmax,qmin;
for(int i=1;i<=n;i++)
{
while(!qmax.empty()&&a[i].x-a[qmax.front()].x>k) qmax.pop_front();
while(!qmin.empty()&&a[i].x-a[qmin.front()].x>k) qmin.pop_front();
while(!qmax.empty()&&a[i].y>=a[qmax.back()].y) qmax.pop_back();
while(!qmin.empty()&&a[i].y<=a[qmin.back()].y) qmin.pop_back();
qmax.push_back(i),qmin.push_back(i);
if(a[qmax.front()].y-a[qmin.front()].y>=d) return 1;
}
return 0;
}
int main()
{
n=read();d=read();
for(int i=1;i<=n;i++) {a[i].x=read();a[i].y=read();}
sort(a+1,a+n+1,cmp);
int l=1,r=1000000,ans=-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
cout<<ans<<"\n";
return 0;
}