zoukankan      html  css  js  c++  java
  • BZOJ1185 HNOI2007 最小矩阵覆盖

    1185: [HNOI2007]最小矩形覆盖

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

    Description

     

    Input

     

    Output

     

    Sample Input

     

    Sample Output

     

    HINT

     

    Source

    先做出凸包,再旋转卡壳
    注意卡上界用叉积,卡左右边界用点积
    代码中定义的除号其实就是点积的函数
    #include <bits/stdc++.h>
    #define ll long long
    #define eps 1e-8
    using namespace std;
    inline int read(){
        int x=0;int f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f-=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int MAXN=1e6+10;
    struct node{
        double x,y;
    }s[MAXN],p[MAXN],t[10];
    int top,n;
    double ans=1e60;
    inline  bool operator < (node n,node m){
        return abs(n.y-m.y)<eps?n.x<m.x:n.y<m.y;
    }
    inline node operator + (node n,node m){
        node t;t.x=n.x+m.x;t.y=n.y+m.y;return t;
    }
    inline node operator - (node n,node m){
        node t;t.x=n.x-m.x;t.y=n.y-m.y;return t;
    }
    inline double operator * (node n,node m){
        return n.x*m.y-n.y*m.x;
    }
    inline node operator * (node n,double m){
        node t;t.x=n.x*m;t.y=n.y*m;return t;
    }
    inline int dcmp(node n,node m){
        return n.x-m.x<eps&&n.y-m.y<eps;
    }
    inline double dis(node n){
        return sqrt(n.x*n.x+n.y*n.y);
    }
    inline bool mycmp(node n,node m){
        double t=(n-p[1])*(m-p[1]);
        if(abs(t)<eps) return dis(n-p[1])-dis(m-p[1])<0;
        else return t>0;
    }
    inline double operator / (node n,node m){//dianji
        return n.x*m.x+n.y*m.y;
    }
    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,mycmp);
        s[++top]=p[1];
        for(int i=2;i<=n;i++){
            while(top>1&&(s[top]-s[top-1])*(p[i]-s[top])<eps) top--;
            s[++top]=p[i];
        }
        s[0]=s[top];
    }
    void RC(){
        int l=1,r=1,p=1;
        double R,L,D,H;
        for(int i=0;i<top;i++){
            D=dis(s[i]-s[i+1]);
            while((s[i+1]-s[i])*(s[p+1]-s[i])-(s[i+1]-s[i])*(s[p]-s[i])>-eps) p=(p+1)%top;
            while((s[i+1]-s[i])/(s[r+1]-s[i])-(s[i+1]-s[i])/(s[r]-s[i])>-eps) r=(r+1)%top;
            if(i==0) l=r;
            while((s[i+1]-s[i])/(s[l+1]-s[i])-(s[i+1]-s[i])/(s[l]-s[i])<eps) l=(l+1)%top;
            L=(s[i+1]-s[i])/(s[l]-s[i])/D;R=(s[i+1]-s[i])/(s[r]-s[i])/D;
            H=(s[i+1]-s[i])*(s[p]-s[i])/D;
            if(H<0) H=-H;
            //cout<<l<<' '<<r<<endl;
            double tmp=(R-L)*H;
            if(tmp<ans){
                ans=tmp;
                t[0]=s[i]+(s[i+1]-s[i])*(R/D);
                t[1]=t[0]+(s[r]-t[0])*(H/dis(t[0]-s[r]));
                t[2]=t[1]-(t[0]-s[i])*((R-L)/dis(s[i]-t[0]));
                t[3]=t[2]-(t[1]-t[0]);
            }
        }
    }
    int main(){
        //freopen("All.in","r",stdin);
        //freopen("a.out","w",stdout);
        n=read();
        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<=3;i++){
            if(t[i]<t[fir]) fir=i;
        }
        for(int i=0;i<=3;i++){
            printf("%.5lf %.5lf
    ",t[(i+fir)%4].x,t[(i+fir)%4].y);
        }
        return 0;
    }
    

      

     
  • 相关阅读:
    SDOI2017 R2泛做
    类似静态区间逆序对的题的一些做法
    友链&&日记
    注意事项以及一些奇怪的姿势
    关于各种算法以及好的blog的整理(持续更新)
    PKUSC2019游记
    洛谷P5398 [Ynoi2018]GOSICK(二次离线莫队)
    洛谷P4887 第十四分块(前体)(二次离线莫队)
    [51nod]1678 lyk与gcd(莫比乌斯反演)
    LOJ#557. 「Antileaf's Round」你这衣服租来的吗(FHQ Treap+珂朵莉树)
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/8007276.html
Copyright © 2011-2022 走看看