Try Again

[HAOI2007]覆盖问题

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

很显然,二分搜索,找出每次点的上下左右进行递归判断,当层数大于3的时候就返回。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include <map>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 1044266558
#define mem(a) (memset(a,0,sizeof(a)))
#define inf 2e9
typedef long long ll;
int x[20005],y[20005],n,vis[20005];
void check(int xl,int xr,int yd,int yu,int depth)
{
    for(int i=0;i<n;i++)
    {
        if(!vis[i] && x[i]>=xl && x[i]<=xr && y[i]>=yd && y[i]<=yu) 
            vis[i]=depth;
    }
}
bool dfs(int depth,int mid)
{
    int xl=inf,xr=-inf,yu=-inf,yd=inf;
    for(int i=1;i<=n;i++)
    {
        if(vis[i]) continue;
        xl=min(xl,x[i]);
        xr=max(xr,x[i]);
        yd=min(yd,y[i]);
        yu=max(yu,y[i]);
    }
    if(max(xr-xl,yu-yd)<=mid) return true;
    if(depth==3) return false;
    for(int i=1;i<=2;i++)
    {
        for(int j=1;j<=2;j++)
        {
            if(i==1)
            {
                if(j==1) check(xl,xl+mid,yd,yd+mid,depth);
                else check(xl,xl+mid,yu-mid,yu,depth); 
            }
            else 
            {
                if(j==1) check(xr-mid,xr,yd,yd+mid,depth);
                else check(xr-mid,xr,yu-mid,yu,depth);
            }
            if(dfs(depth+1,mid)) return true;
            for(int k=1;k<=n;k++)
                if(vis[k]==depth) vis[k]=false;
        }
    }
    return false;
}
bool solve(int mid)
{
    memset(vis,false,sizeof(vis));
    return dfs(1,mid);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
    }
    int l=0,mid,top,r=inf;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(solve(mid)){top=mid;r=mid-1;}
        else l=mid+1;
    }
    printf("%d\n",top);
    return 0;
}

 

posted @ 2018-01-15 16:35  十年换你一句好久不见  阅读(248)  评论(0编辑  收藏  举报