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

    1185: [HNOI2007]最小矩形覆盖

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
    Submit: 1426  Solved: 648
    [Submit][Status][Discuss]

    Description

     

    Input

     

    Output

     

    Sample Input

     

    Sample Output

     

    HINT

     

    Source

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=1e5+5;
    const double eps=1e-8;
    double ans=1e60;
    struct Vector{
        double x,y;
        Vector(double x=0,double y=0):x(x),y(y){}
    }p[N],q[N],t[5];int n,top;
    Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
    Vector operator - (Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
    Vector operator * (Vector A,double p){return Vector(A.x*p,A.y*p);}
    Vector operator / (Vector A,double p){return Vector(A.x/p,A.y/p);}
    double operator * (Vector A,Vector B){return A.x*B.y-A.y*B.x;;}
    double operator / (Vector A,Vector B){return A.x*B.x+A.y*B.y;;}
    bool operator<(Vector a,Vector b){
        return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;
    }
    bool operator==(Vector a,Vector b){
        return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;
    }
    double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;}
    double Length(Vector A){return sqrt(Dot(A,A));}
    double Angle(Vector A,Vector B){return acos(Dot(A,B)/(Length(A)*Length(B)));}
    double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}
    double Area2(Vector A,Vector B,Vector C){return Cross(B-A,C-A);}
    bool cmp(Vector a,Vector b){
        double t=(a-p[1])*(b-p[1]);
        if(fabs(t)<eps) return Length(p[1]-a)-Length(p[1]-b)<0;
        else return t>0;
    }
    void graham(){//凸包 
        for(int i=2;i<=n;i++) if(p[i]<p[1]) swap(p[i],p[1]);
        sort(p+2,p+n+1,cmp);
        q[++top]=p[1];
        for(int i=2;i<=n;i++){
            while(top>1&&(q[top]-q[top-1])*(p[i]-q[top])<eps) top--;
            q[++top]=p[i];
        }
        q[0]=q[top];
    }
    void RC(){//旋转卡壳 
        int l=1,r=1,p=1;
        double L,R,D,H;
        for(int i=0;i<top;i++){
            D=Length(q[i]-q[i+1]);
            while((q[i+1]-q[i])*(q[p+1]-q[i])-(q[i+1]-q[i])*(q[p]-q[i])>-eps) p=(p+1)%top;
            while((q[i+1]-q[i])/(q[r+1]-q[i])-(q[i+1]-q[i])/(q[r]-q[i])>-eps) r=(r+1)%top;
            if(i==0) l=r;
            while((q[i+1]-q[i])/(q[l+1]-q[i])-(q[i+1]-q[i])/(q[l]-q[i])<eps) l=(l+1)%top;
                L=(q[i+1]-q[i])/(q[l]-q[i])/D,R=(q[i+1]-q[i])/(q[r]-q[i])/D;
            H=(q[i+1]-q[i])*(q[p]-q[i])/D;
            if(H<0) H=-H;
            double tmp=(R-L)*H;
            if(tmp<ans){
                ans=tmp;
                t[0]=q[i]+(q[i+1]-q[i])*(R/D);
                t[1]=t[0]+(q[r]-t[0])*(H/Length(t[0]-q[r]));
                t[2]=t[1]-(t[0]-q[i])*((R-L)/Length(q[i]-t[0]));
                t[3]=t[2]-(t[1]-t[0]);
            }
        }
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
        graham();
        RC();
        printf("%.5lf
    ",ans);
        int fir=0;
        for(int i=1;i<4;i++) if(t[i]<t[fir]) fir=i;
        for(int i=0;i<4;i++){//某些OJ评测卡精度.. 比如,洛谷
            if(fabs(t[(i+fir)%4].x)<1e-6) printf("0.00000 ");else printf("%.5lf ",t[(i+fir)%4].x);
            if(fabs(t[(i+fir)%4].y)<1e-6) printf("0.00000
    ");else printf("%.5lf
    ",t[(i+fir)%4].y);
        }
        return 0;
    }
    /*
    Sample Input
    6
    1.0 3.00000
    1 4.00000
    2.00000 1
    3 0.00000
    3.00000 6
    6.0 3.0
    
    Sample Output
    18.00000
    3.00000 0.00000
    6.00000 3.00000
    3.00000 6.00000
    0.00000 3.00000
    */
  • 相关阅读:
    CSS hack
    字符串中常用的方法
    排序算法
    拾遗
    数组类型检测
    数组常用的方法
    go 文件服务器(标准库) 添加关机,睡眠,退出功能
    go cmd 交互 初始化执行某些命令
    go 内网IP及外网IP获取
    go 快排实现
  • 原文地址:https://www.cnblogs.com/shenben/p/6285592.html
Copyright © 2011-2022 走看看