• BZOJ:1185: [HNOI2007]最小矩形覆盖


    1185: [HNOI2007]最小矩形覆盖

    这计算几何……果然很烦……

    发现自己不会旋转卡壳,补了下,然后发现求凸包也不会……

    凸包:找一个最左下的点,其他点按照与它连边的夹角排序,然后维护一个栈用斜率判定。

    旋转卡壳:枚举一条边,用叉积和点积维护另外三条边(联系叉积和点积的几何意义,叉积最大即为对边,点积最大最小即为邻边)

    找来5份标程对拍……啥?4个不同的输出,相同的两个完全是错的……

    自己拍吧T_T(花了一下午)

    神TM卡double

    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    #define MN 510001
    #define ld long double
    #define eps 1e-9
    using namespace std;
    
    struct po{ld x,y;}p[MN],a,b,MMH[4];
    ld mmh=1/0.;
    int n,m,st[MN],top,j,k,l;
    po operator - (po a,po b){return po{a.x-b.x,a.y-b.y};}
    po operator + (po a,po b){return po{a.x+b.x,a.y+b.y};}
    po operator * (po a,ld x){return po{a.x*x,a.y*x};}
    inline ld ABS(ld x){return x<0?-x:x;}
    inline ld sqr(ld x){return x*x;}
    inline ld dis(po a,po b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
    inline ld dj(po a,po b){return a.y*b.x-b.y*a.x;}
    inline ld dj(po a,po b,po c){return (b.y-a.y)*(c.x-a.x)-(c.y-a.y)*(b.x-a.x);}
    inline ld dj(po a,po b,po c,po d){return (b.y-a.y)*(d.x-c.x)-(d.y-c.y)*(b.x-a.x);}
    inline ld det(po a,po b){return a.x*b.x+a.y*b.y;}
    inline ld det(po a,po b,po c){return (b.x-a.x)*(c.x-a.x)+(c.y-a.y)*(b.y-a.y);}
    bool cmp(po a,po b){
        ld t=dj(p[1],a,b);
        if (abs(t)>eps) return t<0;else return dis(a,p[1])<dis(b,p[1]);
    }
    int main(){
        register int i;
        scanf("%d",&n);
        for (i=1;i<=n;i++) scanf("%Lf%Lf",&p[i].x,&p[i].y);
        for (i=2;i<=n;i++) if (p[i].y<p[1].y||(p[i].y==p[1].y&&p[i].x<p[1].x)) swap(p[1],p[i]);
        sort(p+2,p+1+n,cmp);
        
        for (top=0,i=1;i<=n;i++){
            while (top>1&&dj(p[st[top-1]],p[st[top]],p[i])>=-eps) top--;
            st[++top]=i;
        }
        st[0]=st[top];st[top+1]=st[1];
        for (i=1,j=k=l=2;i<=top;i++){
            while (dj(p[st[i]],p[st[i+1]],p[st[j]])+eps>dj(p[st[i]],p[st[i+1]],p[st[j+1]])) j=j==top?1:j+1;
            
            while (det(p[st[i]],p[st[i+1]],p[st[k]])-eps<det(p[st[i]],p[st[i+1]],p[st[k+1]])) k=k==top?1:k+1;
            
            if (i==1) l=k;
            while (det(p[st[i]],p[st[i+1]],p[st[l]])+eps>det(p[st[i]],p[st[i+1]],p[st[l+1]])) l=l==top?1:l+1;
            
            a=p[st[i+1]]-p[st[i]];
            ld D=dis(p[st[i]],p[st[i+1]]);
            ld H=ABS(det(p[st[k]]-p[st[i+1]],a))/D+ABS(det(p[st[l]]-p[st[i]],a))/D+D;
            a=p[st[i+1]]-p[st[i]];a=po{-a.y,a.x};
            ld W=(ABS(det(p[st[k]]-p[st[i]],a))+ABS(det(p[st[k]]-p[st[j]],a)))/D;
            ld S=H*W;
            if (S<mmh){
                mmh=S;
                a=p[st[i+1]]-p[st[i]];
                MMH[0]=p[st[i+1]]+(p[st[i+1]]-p[st[i]])*(ABS(det(p[st[k]]-p[st[i+1]],a))/D/D);
                a=p[st[i+1]]-p[st[i]];a=po{-a.y,a.x};
                MMH[1]=MMH[0]+a*(W/D);
                a=p[st[i+1]]-p[st[i]];a=po{-a.x,-a.y};
                MMH[2]=MMH[1]+a*(H/D);
                a=p[st[i+1]]-p[st[i]];a=po{a.y,-a.x};
                MMH[3]=MMH[2]+a*(W/D);
            }
        }
        printf("%.5Lf
    ",mmh);
        i=0;
        for (int j=1;j<4;j++)
        if (MMH[j].y<MMH[i].y||(MMH[j].y==MMH[i].y&&MMH[j].x<MMH[i].x)) i=j;
        for (int j=0;j<4;j++) printf("%.5Lf %.5Lf
    ",ABS(MMH[(i+j)%4].x),ABS(MMH[(i+j)%4].y));
    }
    View Code
  • 相关阅读:
    MSSQL—列记录合并
    MSSQL—字符串分离(Split函数)
    如何在ASP.NET Core中自定义Azure Storage File Provider
    从零开始实现ASP.NET Core MVC的插件式开发(六)
    对ASP.NET程序员非常有用的85个工具
    vs-code 配置
    idea-plugin
    VirtualBox中CentOS遇到的问题
    监听器
    线程组复杂场景
  • 原文地址:https://www.cnblogs.com/Enceladus/p/6734466.html
Copyright © 2020-2023  润新知