暴搜 bzoj1052 覆盖问题
问题 B: 覆盖问题
时间限制: 1 Sec 内存限制: 256 MB
题目描述
Description
某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄
膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小树遮起来。我们不妨将山建
立一个平面直角坐标系,设第i棵小树的坐标为(Xi,Yi),3个L*L的正方形的边要求平行与坐标轴,一个点如果在
正方形的边界上,也算作被覆盖。当然,我们希望塑料薄膜面积越小越好,即求L最小值。
Input
第一行有一个正整数N,表示有多少棵树。接下来有N行,第i+1行有2个整数Xi,Yi,表示第i棵树的坐标,保证
不会有2个树的坐标相同。
Output
一行,输出最小的L值。
Sample Input
4
0 1
0 -1
1 0
-1 0
Sample Output
1
HINT
100%的数据,N<=20000
我们对于所有点可以搞出一个覆盖所有点的最小矩形,那么当前的正方形一定与其边相连,而且一定在顶点上(不然有的点在旮旯里覆盖不上,一定不最优),所以枚举四个顶点,枚举三次,暴搜即可。
应该没人想不到这是二分吧?→_→
#pragma GCC optimize("O3")
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 20005
#define inf 100000000
#define ll long long
using namespace std;
int read()
{
int sum=0,f=1;char x=getchar();
while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}
return sum*f;
}
struct node{ll x,y;}a[N];
int n;
bool vis[N];
ll hx=inf,hd=-inf,zx=inf,zd=-inf;
inline bool cmp(node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;}
inline int check(ll h1,ll h2,ll z1,ll z2,ll x,int h)
{
if(h==4)return 0;
ll f1=inf,f2=-inf,g1=inf,g2=-inf;int hh[N];memcpy(hh,vis,sizeof(vis));
for(int i=1;i<=n;i++)if(!vis[i]&&a[i].x<=h1+x&&a[i].y<=z1+x)vis[i]=1;
int s=0;for(int i=1;i<=n;i++)if(vis[i])s++;if(s==n)return 1;
for(int i=1;i<=n;i++)
{
if(vis[i])continue;
if(a[i].x>f2)f2=a[i].x;
if(a[i].x<f1)f1=a[i].x;
if(a[i].y>g2)g2=a[i].y;
if(a[i].y<g1)g1=a[i].y;
}
int k=check(f1,f2,g1,g2,x,h+1);if(k==1)return 1;
memcpy(vis,hh,sizeof(vis));
f1=inf,f2=-inf,g1=inf,g2=-inf;memcpy(hh,vis,sizeof(vis));
for(int i=1;i<=n;i++)if(!vis[i]&&a[i].x<=h1+x&&a[i].y>=z2-x)vis[i]=1;
s=0;for(int i=1;i<=n;i++)if(vis[i])s++;if(s==n)return 1;
for(int i=1;i<=n;i++)
{
if(vis[i])continue;
if(a[i].x>f2)f2=a[i].x;
if(a[i].x<f1)f1=a[i].x;
if(a[i].y>g2)g2=a[i].y;
if(a[i].y<g1)g1=a[i].y;
}
k=check(f1,f2,g1,g2,x,h+1);if(k==1)return 1;
memcpy(vis,hh,sizeof(vis));
f1=inf,f2=-inf,g1=inf,g2=-inf;memcpy(hh,vis,sizeof(vis));
for(int i=1;i<=n;i++)if(!vis[i]&&a[i].x>=h2-x&&a[i].y<=z1+x)vis[i]=1;
s=0;for(int i=1;i<=n;i++)if(vis[i])s++;if(s==n)return 1;
for(int i=1;i<=n;i++)
{
if(vis[i])continue;
if(a[i].x>f2)f2=a[i].x;
if(a[i].x<f1)f1=a[i].x;
if(a[i].y>g2)g2=a[i].y;
if(a[i].y<g1)g1=a[i].y;
}
k=check(f1,f2,g1,g2,x,h+1);if(k==1)return 1;
memcpy(vis,hh,sizeof(vis));
f1=inf,f2=-inf,g1=inf,g2=-inf;memcpy(hh,vis,sizeof(vis));
for(int i=1;i<=n;i++)if(!vis[i]&&a[i].x>=h2-x&&a[i].y>=z2-x)vis[i]=1;
s=0;for(int i=1;i<=n;i++)if(vis[i])s++;if(s==n)return 1;
for(int i=1;i<=n;i++)
{
if(vis[i])continue;
if(a[i].x>f2)f2=a[i].x;
if(a[i].x<f1)f1=a[i].x;
if(a[i].y>g2)g2=a[i].y;
if(a[i].y<g1)g1=a[i].y;
}
k=check(f1,f2,g1,g2,x,h+1);if(k==1)return 1;
memcpy(vis,hh,sizeof(vis));
return 0;
}
int main()
{
n=read();ll x,y;if(n==0){cout<<0;return 0;}
for(int i=1;i<=n;i++)a[i].x=read(),a[i].y=read();
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(a[i].x>hd)hd=a[i].x;
if(a[i].x<hx)hx=a[i].x;
if(a[i].y>zd)zd=a[i].y;
if(a[i].y<zx)zx=a[i].y;
}
ll l=0,r=max(zd-zx,hd-hx),mid,ans;
while(l<=r)
{
mid=(l+r)/2;
memset(vis,0,sizeof(vis));
if(check(hx,hd,zx,zd,mid,1))ans=mid,r=mid-1;
else l=mid+1;
}
cout<<ans;
}