P2698 [USACO12MAR]Flowerpot S 题解

本题题意简单明了。

首先,题目当中 最小 二字,就是在提示我们使用二分。

然后,要求最大值与最小值的差,并且区间长度固定,各位能想到什么?我想到的是使用单调队列维护。

做法:

  1. 首先对输入数组按照 \(x\) 坐标升序排序。
  2. 然后二分花盆长度,跑一次单调队列即可。

所以结束了?代码:

#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;
}
posted @ 2022-04-12 21:39  Plozia  阅读(63)  评论(0编辑  收藏  举报