【UVA10652】Board Wrapping(求凸包面积)

点此看题面

大致题意: 告诉你若干个矩形的重心坐标相对\(y\)轴的偏转角度,求矩形面积和能围住这些矩形的最小凸包面积之比。


矩形面积和

这应该是比较好求的吧。

已经给了你长和宽,直接乘起来累加即可。


最小凸包面积

这道题关键还是在于求凸包面积。

首先,我们要注意将题目中给出的角度转换成弧度,还要记得取相反数,不然调死你。

这段代码可以与旋转函数放在一起:

inline Point Rotate(Vector A,double deg)
{
    register double rad=deg*acos(-1)/180;dcmp(rad)<0&&(rad+=2*acos(-1)),rad=-rad;//将角度转换成弧度,并取相反数
    return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));//返回旋转后的点的坐标
} 

则我们就可以很方便地求出每个矩形四个顶点的坐标了。

枚举四个方向,分别将对应的向量(\(±\frac{s1}2\),\(±\frac{s2}2\))进行旋转,然后加上原先点的坐标即可(\(s1,s2\)分别为长和宽)。

这段代码如下:

A=Point(x,y),
P.p[++P.n]=A+Rotate(Point(s1/2,s2/2),deg),
P.p[++P.n]=A+Rotate(Point(s1/2,-s2/2),deg),
P.p[++P.n]=A+Rotate(Point(-s1/2,s2/2),deg),
P.p[++P.n]=A+Rotate(Point(-s1/2,-s2/2),deg);

这样,我们就可以得到\(4n\)个点,然后将这些点求一个凸包,然后作出凸包面积即可。

这段过程比较板子,可以参考这篇博客:初学计算几何(四)——初识凸包

具体实现详见代码吧。


代码

#include<bits/stdc++.h>
#define N 600
using namespace std;
int n;
namespace ComputationGeometry
{
    #define eps 1e-10
    inline int dcmp(double x) {return fabs(x)<eps?0:(x>0?1:-1);}
    struct Point
    {
        double x,y;
        Point(double nx=0,double ny=0):x(nx),y(ny){}
    };
    typedef Point Vector;
    inline Vector operator + (Point A,Point B) {return Vector(A.x+B.x,A.y+B.y);}
    inline Vector operator - (Point A,Point B) {return Vector(A.x-B.x,A.y-B.y);}
    inline Vector operator * (Vector A,double x) {return Vector(A.x*x,A.y*x);}
    inline Vector operator / (Vector A,double x) {return Vector(A.x/x,A.y/x);}
    inline bool operator < (Vector A,Vector B) {return fabs(A.x-B.x)>eps?A.x<B.x:A.y<B.y;}
    inline double Cro(Vector A,Vector B) {return A.x*B.y-A.y*B.x;}
    inline Point Rotate(Vector A,double deg)//旋转
    {
        register double rad=deg*acos(-1)/180;dcmp(rad)<0&&(rad+=2*acos(-1)),rad=-rad;
        return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
    }
    struct Polygon
    {
        int n;Point p[(N<<2)+5];
        Polygon() {n=0;}
    };
    typedef Polygon ConvexHull;
    inline double PolygonArea(Polygon P)//求多边形(凸包)面积
    {
        register int i;register double res=0;
        for(i=2;i<P.n;++i) res+=Cro(P.p[i]-P.p[1],P.p[i+1]-P.p[1])/2;
        return res;
    }
    inline ConvexHull GetConvexHull(Polygon P)//求凸包
    {
        register int i,t;register Polygon S=P;register ConvexHull res;
        for(sort(S.p+1,S.p+S.n+1),i=1;i<=S.n;++i)
        {
            while(res.n>1&&dcmp(Cro(res.p[res.n]-res.p[res.n-1],S.p[i]-res.p[res.n-1]))<=0) --res.n;
            res.p[++res.n]=S.p[i];
        }
        for(t=res.n,i=S.n-1;i;--i)
        {
            while(res.n>t&&dcmp(Cro(res.p[res.n]-res.p[res.n-1],S.p[i]-res.p[res.n-1]))<=0) --res.n;
            res.p[++res.n]=S.p[i];
        }
        return res;
    }
};
using namespace ComputationGeometry;
int main()
{
    freopen("a.in","r",stdin);
    register int test_tot,i;register double x,y,s1,s2,deg,sum;register Point A;register Polygon P;register ConvexHull H;scanf("%d",&test_tot);
    while(test_tot--)
    {
        for(scanf("%d",&n),P.n=sum=0,i=1;i<=n;++i)
        {
            scanf("%lf%lf%lf%lf%lf",&x,&y,&s1,&s2,&deg),A=Point(x,y),sum+=s1*s2,//同时统计矩形面积和
            P.p[++P.n]=A+Rotate(Point(s1/2,s2/2),deg),P.p[++P.n]=A+Rotate(Point(s1/2,-s2/2),deg),P.p[++P.n]=A+Rotate(Point(-s1/2,s2/2),deg),P.p[++P.n]=A+Rotate(Point(-s1/2,-s2/2),deg);//存储点
        }
        printf("%.1lf %%\n",100*sum/PolygonArea(GetConvexHull(P)));//计算答案
    }
    return 0;
}

原文地址:https://www.cnblogs.com/chenxiaoran666/p/UVA10652.html

时间: 2024-11-05 10:05:58

【UVA10652】Board Wrapping(求凸包面积)的相关文章

poj 3348 Cows 求凸包面积

题目链接 大意: 求凸包的面积. #include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue>

UVA 10652 Board Wrapping(凸包)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32286 [思路] 凸包 根据角度与中心点求出长方形所有点来,然后就可以应用凸包算法了. [代码] #include<cmath> #include<cstdio> #include<algorithm> using namespace std; const double PI = acos(-1.0); double torad(doub

Uva - 10652 Board Wrapping(凸包)

给定一些长方形的坐标,求长方形的面积与围住这些长方形面积的凸包的百分比. 首先假设长方形都是水平放置,那么根据长和宽还有中心坐标,可以求出四个顶点的坐标,然后求出从中心指向顶点的向量,和角度转化成的弧度,向量旋转之后得到一个新的向量 是由中心指向新的顶点,加上中心点就得到新的顶点的坐标.可以画图理解. 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm&

Board Wrapping(计算几何求凸包加向量的旋转)

UVA - 10652 Board Wrapping Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description Problem B Board Wrapping Input: standard input Output: standard output Time Limit: 2 seconds The small sa

简单几何(向量旋转+凸包+多边形面积) UVA 10652 Board Wrapping

题目传送门 题意:告诉若干个矩形的信息,问他们在凸多边形中所占的面积比例 分析:训练指南P272,矩形面积长*宽,只要计算出所有的点,用凸包后再求多边形面积.已知矩形的中心,向量在原点参考点再旋转,角度要转换成弧度制. /************************************************ * Author :Running_Time * Created Time :2015/11/10 星期二 10:34:43 * File Name :UVA_10652.cpp

uva 10652 Board Wrapping (计算几何-凸包)

Problem B Board Wrapping Input: standard input Output: standard output Time Limit: 2 seconds The small sawmill in Mission, British Columbia, has developed a brand new way of packaging boards for drying. By fixating the boards in special moulds, the b

poj 3348 Cows 凸包 求多边形面积 计算几何 难度:0 Source:CCC207

Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7038   Accepted: 3242 Description Your friend to the south is interested in building fences and turning plowshares into swords. In order to help with his overseas adventure, they are f

Cows 计算几何 求凸包 求多边形面积

题目链接:https://cn.vjudge.net/problem/POJ-3348 题意 啊模版题啊 求凸包的面积,除50即可 思路 求凸包的面积,除50即可 提交过程 AC 代码 #include <cmath> #include <cstdio> #include <vector> #include <algorithm> using namespace std; const double eps=1e-10; struct Point{ doubl

UVA 10652 Board Wrapping(二维凸包)

传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组先输入木板个数n,接下来n行,每行x,y,w,h,j.(x,y)是木板中心的坐标,w是宽,h是高,j是顺时针旋转的角度. 木板互不相交. 输出:对于每组数据,输出木板总面积占包装总面积的百分比,保留小数点后1位. 题解:典型的二维凸包问题,理解并调用模板即可. #include <math.h>