• [HNOI2007]最小矩形覆盖


    Description

    给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形,

    输出所求矩形的面积和四个顶点坐标

    Input

    第一行为一个整数n(3<=n<=50000)

    从第2至第n+1行每行有两个浮点数,表示一个顶点的x和y坐标,不用科学计数法

    Output

    第一行为一个浮点数,表示所求矩形的面积(精确到小数点后5位),

    接下来4行每行表示一个顶点坐标,要求第一行为y坐标最小的顶点,

    其后按逆时针输出顶点坐标.如果用相同y坐标,先输出最小x坐标的顶点

    Sample Input

    6 1.0 3.00000
    1 4.00000
    2.0000 1
    3 0.0000
    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

    Solution

    说实话这个题笔者做的实在是非常难受身心俱疲。首先之前打过一遍然后挂了,怎么调都调不出来之后又重构代码,然后又是各种调不出来,之后过了样例,又是各种wa,什么特判都加完了之后终于是A掉了。。。

    总体思路大致是这个样子,经过一系列奇奇怪怪的证明之后我们可以发现,我们要求的那个矩形一定有一条边在这些点的凸包的边上,然后旋转卡壳枚举边,求出来就可以了,代码非常难搞,细节非常多,笔者一开始被卡掉了0.0001的精度,结果找着黄学长的一顿乱改,结果改到最后,快长得一样了。。。。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define ll long long
    #define inf 50000000
    #define re register
    #define MAXN 50005
    #define eps 1e-8
    using namespace std;
    double ans=1e60;
    int n,top;
    struct P{
        double x,y;
        P(){}
        P(double _x,double _y):x(_x),y(_y){}
        friend bool operator<(P a,P b){
            return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;
        }
        friend bool operator==(P a,P b){
            return fabs(a.x-b.x)<eps&&fabs(a.y<b.y)<eps;
        }
        friend bool operator!=(P a,P b){
            return !(a==b);
        }
        friend P operator+(P a,P b){
            return P(a.x+b.x,a.y+b.y);
        }
        friend P operator-(P a,P b){
            return P(a.x-b.x,a.y-b.y);
        }
        friend double operator *(P a,P b){
            return a.x*b.y-a.y*b.x;
        }
        friend P operator *(P a,double b){
            return P(a.x*b,a.y*b);
        }
        friend double operator /(P a,P b){
            return a.x*b.x+a.y*b.y;
        }
        friend double dis(P a){
            return sqrt(a.x*a.x+a.y*a.y);
        }
    };
    P p[MAXN],q[MAXN],t[5];
    inline bool cmp(P a,P b)
    {
        double k=(a-p[1])*(b-p[1]);
        if(fabs(k)<eps) return dis(p[1]-a)-dis(p[1]-b)<0;
        return k>0;
    }
    inline void Graham()
    {
        for(re 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(re 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];
    }
    inline void solve()
    {
        int l=1,r=1,p=1;
        double L,R,D,H;
        for(re int i=0;i<top;i++){
            D=dis(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/dis(t[0]-q[r]));
                t[2]=t[1]-(t[0]-q[i])*((R-L)/dis(q[i]-t[0]));
                t[3]=t[2]-(t[1]-t[0]);
            }
        }
    }
    int main()
    {
        cin>>n;
        for(re int i=1;i<=n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        Graham();
        solve();
        printf("%.5lf
    " ,ans);
        int fir=0;
        for(re int i=1;i<=3;i++)
            if(t[i]<t[fir])
                fir=i;
        for(re int i=0;i<=3;i++)
            printf("%.5lf %.5lf
    ",fabs(t[(i+fir)%4].x)>1e-12?t[(i+fir)%4].x:0.00000,fabs(t[(i+fir)%4].y)>1e-12?t[(i+fir)%4].y:0.00000);
        return 0;
    }
    
  • 相关阅读:
    十、collection的作用+变量
    python借助ADB工具实现自动化操作手机
    selenium 对浏览器标签页进行关闭和切换
    python编写shell脚本
    报错解决——# Creating Server TCP listening socket *:6379: bind: Address already in use
    Mac 报错:-bash: telnet: command not found
    Mac快捷键大全及cheatsheet插件
    报错解决——xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
    Mac破解免费office软件
    python 当前时间多加一天、一小时、一分钟
  • 原文地址:https://www.cnblogs.com/victorique/p/8946514.html
Copyright © 2020-2023  润新知