zoukankan      html  css  js  c++  java
  • 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖

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

    Description

     

    题解

    显然矩形一边一定在凸包一边上

    旋转卡壳维护其他三条边经过的顶点

    更新答案

    这题1A欸嘿嘿

    代码

    //by 减维
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<bitset>
    #include<set>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<ctime>
    #include<algorithm>
    #define LL long long
    #define db double
    #define inf 1<<30
    #define maxn 50005
    #define eps 1e-8
    using namespace std;
    
    struct node{
        db x,y;
    }poi[maxn],sta[maxn],ans[15];
    
    int n,top;
    db mn=100000000.00;
    
    bool cmp(node x,node y){if(x.x==y.x)return x.y<y.y;return x.x<y.x;}
    bool cm2(node x,node y){if(x.x==y.x)return x.y>y.y;return x.x>y.x;}
    node operator - (node x,node y){return (node){x.x-y.x,x.y-y.y};}
    node operator + (node x,node y){return (node){x.x+y.x,x.y+y.y};}
    node operator * (node x,db y){return (node){x.x*y,x.y*y};}
    node operator * (db x,node y){return (node){x*y.x,x*y.y};}
    db operator * (node x,node y){return x.x*y.y-x.y*y.x;}
    db operator / (node x,node y){return x.x*y.x+x.y*y.y;}
    bool operator == (node x,node y){return x.x==y.x&&x.y==y.y;}
    bool operator > (node x,node y){if(x.y==y.y)return x.x>x.y;return x.y>y.y;}
    db dis(node x,node y){return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));}
    
    void solve()
    {
        db ds,h,ll,rr;
        int t=0,l=0,r=0;
        sta[0]=sta[top];
        for(int i=0;i<top;++i)
        {
            ds=dis(sta[i],sta[i+1]);
            while((sta[i+1]-sta[i])*(sta[t+1]-sta[i])-(sta[i+1]-sta[i])*(sta[t]-sta[i])>-eps)t=(t+1)%top;
            while((sta[i+1]-sta[i])/(sta[r+1]-sta[i])-(sta[i+1]-sta[i])/(sta[r]-sta[i])>-eps)r=(r+1)%top;
            if(i==0)l=r;
            while((sta[i+1]-sta[i])/(sta[l]-sta[i])-(sta[i+1]-sta[i])/(sta[l+1]-sta[i])>-eps)l=(l+1)%top;
            ll=(sta[i+1]-sta[i])/(sta[l]-sta[i])/ds;
            rr=(sta[i+1]-sta[i])/(sta[r]-sta[i])/ds;
            h=(sta[i+1]-sta[i])*(sta[t]-sta[i])/ds;
            if(mn>(rr-ll)*h){
                mn=(rr-ll)*h;
                ans[0]=sta[i]+(sta[i+1]-sta[i])*(rr/ds);
                ans[1]=ans[0]+(sta[r]-ans[0])*(h/dis(sta[r],ans[0]));
                ans[2]=ans[1]+(sta[t]-ans[1])*((rr-ll)/dis(sta[t],ans[1]));
                ans[3]=ans[2]+(ans[0]-ans[1]);
            }
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%lf%lf",&poi[i].x,&poi[i].y);
        sort(poi+1,poi+n+1,cmp);
        sta[++top]=poi[1];sta[++top]=poi[2];
        for(int i=3;i<=n;++i){
            while((poi[i]-sta[top-1])*(sta[top]-sta[top-1])>-eps&&top>=2)top--;
            sta[++top]=poi[i];
        }
        sort(poi+1,poi+n+1,cm2);
        int sa=top;
        if(sta[top]==poi[1])sta[++top]=poi[2],sa--;
        else sta[++top]=poi[1],sta[++top]=poi[2];
        for(int i=3;i<=n;++i){
            while((poi[i]-sta[top-1])*(sta[top]-sta[top-1])>-eps&&top>sa)top--;
            sta[++top]=poi[i];
        }
        top--;
        solve();
        printf("%.5lf
    ",mn);
        int fir=0;
        for(int i=1;i<=3;++i)if(ans[fir]>ans[i])fir=i;
        for(int i=0;i<=3;++i)printf("%.5lf %.5lf
    ",ans[(fir+i)%4],ans[(fir+i)%4]);
        return 0;
    }
  • 相关阅读:
    程序员最好也要懂的一些沟通说服技巧
    MapFields和并行计算(OpenFOAM)
    Python 调用自己编写的Class
    Ubuntu 图形桌面死机重启(机器不重启)
    Ubuntu 安装 Visual Studio Code
    Ubuntu图形界面和终端界面切换快捷键
    Linux直接在通过终端打开图片文件
    Linux新建环境变量快速切换到文件夹(export)
    Python文件读写(一)
    Dictonary(Python)(一)
  • 原文地址:https://www.cnblogs.com/rir1715/p/8136747.html
Copyright © 2011-2022 走看看