1. 程式人生 > 其它 >P2698 [USACO12MAR]Flowerpot S 題解

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;
}