zoukankan      html  css  js  c++  java
  • bzoj1052: [HAOI2007]覆盖问题(二分+构造)

      貌似又写出了常数挺优(至少不劣)的代码>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
    ",l);
        return 0;
    }
    View Code
  • 相关阅读:
    sql server:Monty Hall problem (蒙提霍尔问题)
    sql server: Graphs, Trees, Hierarchies and Recursive Queries
    csharp:SMO run sql script
    csharp: sum columns or rows in a dataTable
    sql server: quering roles, schemas, users,logins
    sql: Query to Display Foreign Key Relationships and Name of the Constraint for Each Table in Database
    Hadoop基本概念
    OVS架构解析
    Linux下实现修改IP选项字段
    linux下实现UDP通信
  • 原文地址:https://www.cnblogs.com/Sakits/p/7466891.html
Copyright © 2011-2022 走看看