zoukankan      html  css  js  c++  java
  • UVA 10652 Board Wrapping(二维凸包)

    传送门

    刘汝佳《算法竞赛入门经典》P272例题6包装木板

    题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比。

    输入:t组数据,每组先输入木板个数n,接下来n行,每行x,y,w,h,j。(x,y)是木板中心的坐标,w是宽,h是高,j是顺时针旋转的角度。

       木板互不相交。

    输出:对于每组数据,输出木板总面积占包装总面积的百分比,保留小数点后1位。

    题解:典型的二维凸包问题,理解并调用模板即可。

    附上凸包的证明过程,只看网址里的图,注意sort是极角排序:传送门

    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    using namespace std;
    typedef struct Point{
        double x,y;
        Point(double x=0,double y=0):x(x),y(y){}
    }Vector;
    Vector operator + (Vector A,Vector B)
    {
        return Vector(A.x+B.x,A.y+B.y);
    }
    Vector operator - (Point A,Point B)
    {
        return Vector(A.x-B.x,A.y-B.y);
    }
    bool operator <(const Point &a,const Point &b)
    {
        return a.x<b.x||(a.x==b.x&&a.y<b.y);
    }
    double Cross(Vector A,Vector B)
    {
        return A.x*B.y-A.y*B.x;
    }
    Vector Rotate(Vector A,double rad) //向量旋转
    {
        return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
    }
    double ConvexPolygonArea(Point *p,int n)
    {
        double area=0;
        for(int i=1;i<n-1;i++)
            area+=Cross(p[i]-p[0],p[i+1]-p[0]);
        return area/2;
    }
    double torad(double deg)
    {
        return deg/180*acos(-1);
    }
    int ConvexHull(Point *p,int n,Point* ch) //注意是*ch
    {
        sort(p,p+n);
        //不知道这里为什么不能加unique函数
        //n=unique(p,p+n)-p;
        int m=0;
        for(int i=0;i<n;i++)
        {
            while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
            ch[m++]=p[i];
        }
        int k=m;
        for(int i=n-2;i>=0;i--)  //注意是--不是++
        {
            while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
            ch[m++]=p[i];
        }
        if(n>1) m--;
        return m;//别忘了加m
    }
    int main()
    {
        int T;
        Point P[2500],ch[2500];
        scanf("%d",&T);
        while(T--)
        {
            int n,pc=0;
            double area1=0;
            scanf("%d",&n);
            for(int i=0;i<n;i++)
            {
                double x,y,w,h,j,ang;
                scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&j);
                Point o(x,y);
                ang=-torad(j);
                P[pc++]=o+Rotate(Vector(-w/2,-h/2),ang);
                P[pc++]=o+Rotate(Vector(w/2,-h/2),ang);
                P[pc++]=o+Rotate(Vector(-w/2,h/2),ang);
                P[pc++]=o+Rotate(Vector(w/2,h/2),ang);
                area1+=w*h; //矩形总面积
            }
            int m=ConvexHull(P,pc,ch);
            double area2=ConvexPolygonArea(ch,m); //凸包面积
            //%被看做是格式说明符 所以要输出两个百分号
            printf("%.1lf %%
    ",area1*100/area2);
        }
        return 0;
    }
  • 相关阅读:
    在请求中使用XML Publisher生成文件报错
    Oracle Sourcing Implementation and Administration Guide(转)
    API To Import Negotiations(转)
    使用POI动态更新导出的EXCEL模板中的列
    使用POI设置导出的EXCEL锁定指定的单元格
    QML获取随机颜色
    Access导出excel
    Component
    QML中打印
    Qt Quick Dialogs
  • 原文地址:https://www.cnblogs.com/Ritchie/p/5506232.html
Copyright © 2011-2022 走看看