zoukankan      html  css  js  c++  java
  • bzoj1185: [HNOI2007]最小矩形覆盖

    Description

     

    顺序枚举凸包上的边确定矩形一边,旋转卡壳确定在矩形另外三边上的点

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    typedef long double ld;
    const ld _0=1e-7;
    struct vec{ld x,y;};
    struct line{vec p,v;};
    vec operator+(vec a,vec b){return (vec){a.x+b.x,a.y+b.y};}
    vec operator-(vec a,vec b){return (vec){a.x-b.x,a.y-b.y};}
    vec operator*(vec a,ld x){return (vec){a.x*x,a.y*x};}
    ld operator*(vec a,vec b){return a.x*b.y-a.y*b.x;}
    bool operator<(vec a,vec b){return a*b>0;}
    ld abs(vec a){return sqrt(a.x*a.x+a.y*a.y);}
    vec operator&(line a,line b){return a.p+a.v*((b.v*(a.p-b.p))/(a.v*b.v));}
    int n,p,p1,p2,p3,pa[4];
    vec vs[50010],ps[100010],m;
    ld ans=1e40;
    vec as[4];
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++)scanf("%llf%llf",&vs[i].x,&vs[i].y);
        for(int i=1;i<n;i++)if(vs[i].x<vs[p].x||vs[i].x==vs[p].x&&vs[i].y<vs[p].y)p=i;
        m=vs[p];
        for(int i=0;i<n;i++){
            vs[i]=vs[i]-m;
            if(abs(vs[i])<_0)vs[i--]=vs[--n];
        }
        std::sort(vs,vs+n);
        ps[0]=(vec){0,0};
        ps[p=1]=vs[0];
        for(int i=1;i<n;i++){
            while(p&&(ps[p]-ps[p-1])*(vs[i]-ps[p])<_0)--p;
            ps[++p]=vs[i];
        }
        n=p+1;
        for(int i=0;i<=n;i++)ps[i+n]=ps[i];
        int n0=n;
        n=n*2+1;
        for(p=0,p1=p2=p3=1;p<n0;p++){
            vec w=ps[p+1]-ps[p];
            if(abs(w)<_0)continue;
            while(p2<n&&w*(ps[p2+1]-ps[p])>w*(ps[p2]-ps[p]))++p2;
            ld x=w*(ps[p2]-ps[p])/abs(w);
            if(p2>p3)p3=p2;
            w=(vec){-w.y,w.x};
            while(p1<n&&w*(ps[p1+1]-ps[p])<w*(ps[p1]-ps[p]))++p1;
            while(p3<n&&w*(ps[p3+1]-ps[p])>w*(ps[p3]-ps[p]))++p3;
            ld y=w*(ps[p3]-ps[p])/abs(w)-w*(ps[p1]-ps[p])/abs(w);
            ld S=x*y;
            if(S<ans){
                ans=S;
                pa[0]=p;pa[1]=p1;pa[2]=p2;pa[3]=p3;
            }
        }
        p=pa[0];p1=pa[1];p2=pa[2];p3=pa[3];
        vec w=ps[p+1]-ps[p];
        line l0=(line){ps[p],w};
        line l2=(line){ps[p2],w};
        w=(vec){-w.y,w.x};
        line l1=(line){ps[p1],w};
        line l3=(line){ps[p3],w};
        as[0]=(l0&l1)+m;
        as[1]=(l1&l2)+m;
        as[2]=(l2&l3)+m;
        as[3]=(l3&l0)+m;
        p=0;
        for(int i=1;i<4;i++)if(as[i].y<as[p].y-_0||fabs(as[i].y-as[p].y)<_0&&as[i].x<as[p].x-_0)p=i;
        printf("%.5lf
    ",(double)ans);
        for(int i=0;i<4;i++)printf("%.5lf %.5lf
    ",(double)as[i+p&3].x,(double)as[i+p&3].y);
        return 0;
    }
  • 相关阅读:
    DBS-Oracle:表的连接查询
    权益保护-产权保护-申请:如何撰写专利申请所需材料
    权益保护-产权保护:软件著作权
    权益保护-产权保护:专利申请
    Code-C#:手机号码验证
    软件-数据库-数据库管理工具-Navicat:百科
    WCF:目录
    WCF:百科
    ASP.NET Core-组件-后台任务:Hangfire
    ASP.NET Core-组件:目录
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5622242.html
Copyright © 2011-2022 走看看