码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1052: [HAOI2007]覆盖问题(二分+构造)

时间:2017-09-02 17:00:32      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:getc   ++   div   iostream   using   hid   poi   二分答案   long   

  貌似又写出了常数挺优(至少不劣)的代码>v< 930+人AC #49

  写了个O(nlogn)貌似比一些人O(n)还快2333333

  这题还是先二分答案,check比较麻烦

  显然正方形一定以最左上或最右上或最左下或最右下的点为端点来盖,盖了一个之后再拿一个枚举剩下的点作为四个端点来盖,最后一个直接判断剩下的点能不能一次性盖就好了

技术分享
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio> 
#include<algorithm>
#define ll long long 
using namespace std;
const int maxn=20010,inf=1e9;
typedef int poi[maxn];
poi x,y;
int n,m,l,r,mid,mxx,mxy,mnx,mny;
void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<0||c>9)c==-&&(f=-1),c=getchar();
    while(c<=9&&c>=0)k=k*10+c-0,c=getchar();
    k*=f;
}
void getmax(poi x,poi y,int tot,int &mxx,int &mxy,int &mnx,int &mny)
{
    mxx=mxy=-inf;mnx=mny=inf;
    for(int i=1;i<=tot;i++)
    {
        mxx=max(mxx,x[i]);mnx=min(mnx,x[i]);
        mxy=max(mxy,y[i]);mny=min(mny,y[i]);
    }
}
bool check(poi x,poi y,int tot,int dep)
{
    int mxx,mxy,mnx,mny,tot2;
    if(dep>2)
    {
        getmax(x,y,tot,mxx,mxy,mnx,mny);
        return max(mxx-mnx,mxy-mny)<=mid;
    }
    getmax(x,y,tot,mxx,mxy,mnx,mny);
    tot2=0;poi x2,y2;
    for(int i=1;i<=tot;i++)
    if(x[i]>mnx+mid||y[i]<mxy-mid)x2[++tot2]=x[i],y2[tot2]=y[i];
    if(check(x2,y2,tot2,dep+1))return 1;    
    tot2=0;
    for(int i=1;i<=tot;i++)
    if(x[i]<mxx-mid||y[i]<mxy-mid)x2[++tot2]=x[i],y2[tot2]=y[i];
    if(check(x2,y2,tot2,dep+1))return 1;
    tot2=0;
    for(int i=1;i<=tot;i++)
    if(x[i]>mnx+mid||y[i]>mny+mid)x2[++tot2]=x[i],y2[tot2]=y[i];
    if(check(x2,y2,tot2,dep+1))return 1;
    tot2=0;
    for(int i=1;i<=tot;i++)
    if(x[i]<mxx-mid||y[i]>mny+mid)x2[++tot2]=x[i],y2[tot2]=y[i];
    if(check(x2,y2,tot2,dep+1))return 1;
    return 0;
}
int main()
{
    read(n);
    for(int i=1;i<=n;i++)read(x[i]),read(y[i]);
    getmax(x,y,n,mxx,mxy,mnx,mny);
    l=1;r=max(mxx-mnx,mxy-mny);
    while(l<r)
    {
        mid=(l+r)>>1;
        if(check(x,y,n,1))r=mid;
        else l=mid+1;
    }
    printf("%d\n",l);
    return 0;
}
View Code

bzoj1052: [HAOI2007]覆盖问题(二分+构造)

标签:getc   ++   div   iostream   using   hid   poi   二分答案   long   

原文地址:http://www.cnblogs.com/Sakits/p/7466891.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!