暴搜 bzoj1052 覆盖问题

来源:互联网 发布:淘宝助理有mac版 编辑:程序博客网 时间:2024/06/05 10:34

问题 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 longusing 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;}
原创粉丝点击