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

    Description

    传送门

    Solution

    感性理解一下,最小矩形一定是由一条边和凸包上的边重合的。

    然后它就是模板题了。。然而真的好难调,小于大于动不动就打错。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const double eps=1e-9;
    int n;
    struct node{double x,y;
        friend node operator +(node a,node b){return node{a.x+b.x,a.y+b.y};}
        friend node operator -(node a,node b){return node{a.x-b.x,a.y-b.y};}
        friend double operator *(node a,node b){return a.x*b.y-a.y*b.x;}
        friend double operator /(node a,node b){return a.x*b.x+a.y*b.y;}
        friend node operator *(node a,double b) {return node{a.x*b,a.y*b};}
        friend bool operator <(node a,node b) { return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;}
    }p[50010],st[50010],low;
    double dis(node a){return a.x*a.x+a.y*a.y;}
    bool cmp(node a,node b){
        double t=(a-p[1])*(b-p[1]);
        if (fabs(t)<eps) return dis(a-p[1])<dis(b-p[1]);
        return t>0;
    }
    int top=0,now;
    int main()
    {
        scanf("%d",&n);
        low.x=low.y=2147483647;
        scanf("%lf%lf",&p[1].x,&p[1].y);
        for (int i=2;i<=n;i++)
        {
            scanf("%lf%lf",&p[i].x,&p[i].y);    
            if (p[i]<p[1]) swap(p[i],p[1]);    
        }
        sort(p+2,p+n+1,cmp);
        st[++top]=p[1];
        for (int i=2;i<=n;i++)
        {
            while (top>1&&(st[top]-st[top-1])*(p[i]-st[top])<eps) top--;
            st[++top]=p[i];
        }
        st[0]=st[top];
        node pr[4];
        double L,R,D,H,ans=1e10;int l=1,r=1,now=1;
        for (int i=0;i<top;i++)
        {
            D=sqrt(dis(st[i]-st[i+1]));
            while ((st[i+1]-st[i])*(st[now+1]-st[i])>(st[i+1]-st[i])*(st[now]-st[i])-eps) now=(now+1)%top;
            while ((st[i+1]-st[i])/(st[r+1]-st[i])>(st[i+1]-st[i])/(st[r]-st[i])-eps) r=(r+1)%top;
            if (!i) l=r;
            while ((st[i+1]-st[i])/(st[l+1]-st[i])<(st[i+1]-st[i])/(st[l]-st[i])+eps) l=(l+1)%top;
            L=(st[i+1]-st[i])/(st[l]-st[i])/D;R=(st[i+1]-st[i])/(st[r]-st[i])/D;
            H=abs((st[i+1]-st[i])*(st[now]-st[i])/D);
            if ((R-L)*H<ans)
            {
                ans=(R-L)*H;
                pr[0]=st[i]+(st[i+1]-st[i])*(R/D);
                pr[1]=pr[0]+(st[r]-pr[0])*(H/sqrt(dis(pr[0]-st[r])));
                pr[2]=pr[1]-(pr[0]-st[i])*((R-L)/sqrt(dis(st[i]-pr[0])));
                pr[3]=pr[2]-(pr[1]-pr[0]);
            }
        }
        now=0;
        for (int i=1;i<=3;i++) if (pr[i]<pr[now]) now=i;
        printf("%.5f
    ",ans);
        for (int i=0;i<=3;i++) 
        {
            if (pr[(i+now)%4].x>-5*1e-6) pr[(i+now)%4].x=fabs(pr[(i+now)%4].x);
            if (pr[(i+now)%4].y>-5*1e-6) pr[(i+now)%4].y=fabs(pr[(i+now)%4].y);
            printf("%.5f %.5f
    ",pr[(i+now)%4].x,pr[(i+now)%4].y);
        }
    }
  • 相关阅读:
    SAP Hybris使用recipe进行安装时,是如何执行ant命令的?
    实时电商数仓(三)之数据采集(二)搭建日志采集系统的集群(二)建立父工程
    实时电商数仓(一)之系统架构
    gdb 条件断点 + 多线程 +attach
    dpdk tx_pkt_burst rte_pktmbuf_free mbuf释放
    dpdk 网卡初始化 —— 收包
    dpdk 版本变动修改
    rte_mempool_get_priv
    mempool + ring test
    dpdk mempool debug
  • 原文地址:https://www.cnblogs.com/coco-night/p/9496560.html
Copyright © 2011-2022 走看看