uva 10652

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

思路:按照题意将所有矩形顶点坐标存起来,旋转时先旋转从中心出发的向量,求得各个坐标之后,求凸包即可。

水。。。。

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<iostream>
  6 #include<memory.h>
  7 #include<cstdlib>
  8 #include<vector>
  9 #define clc(a,b) memset(a,b,sizeof(a))
 10 #define LL long long int
 11 #define up(i,x,y) for(i=x;i<=y;i++)
 12 #define w(a) while(a)
 13 using namespace std;
 14 const int inf=0x3f3f3f3f;
 15 const int N = 4010;
 16 const double eps = 5*1e-13;
 17 const double pi = acos(-1);
 18
 19 const double PI = acos(-1.0);
 20 double torad(double deg)
 21 {
 22     return deg/180 * PI;
 23 }
 24
 25 struct Point
 26 {
 27     double x, y;
 28     Point(double x=0, double y=0):x(x),y(y) { }
 29 };
 30
 31 typedef Point Vector;
 32
 33 Vector operator + (const Vector& A, const Vector& B)
 34 {
 35     return Vector(A.x+B.x, A.y+B.y);
 36 }
 37 Vector operator - (const Point& A, const Point& B)
 38 {
 39     return Vector(A.x-B.x, A.y-B.y);
 40 }
 41 double Cross(const Vector& A, const Vector& B)
 42 {
 43     return A.x*B.y - A.y*B.x;
 44 }
 45
 46 Vector Rotate(const Vector& A, double rad)
 47 {
 48     return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
 49 }
 50
 51 bool operator < (const Point& p1, const Point& p2)
 52 {
 53     return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
 54 }
 55
 56 bool operator == (const Point& p1, const Point& p2)
 57 {
 58     return p1.x == p2.x && p1.y == p2.y;
 59 }
 60
 61 // 点集凸包
 62 // 如果不希望在凸包的边上有输入点,把两个 <= 改成 <
 63 // 如果不介意点集被修改,可以改成传递引用
 64 vector<Point> ConvexHull(vector<Point> p)
 65 {
 66     // 预处理,删除重复点
 67     sort(p.begin(), p.end());
 68     p.erase(unique(p.begin(), p.end()), p.end());
 69
 70     int n = p.size();
 71     int m = 0;
 72     vector<Point> ch(n+1);
 73     for(int i = 0; i < n; i++)
 74     {
 75         while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
 76         ch[m++] = p[i];
 77     }
 78     int k = m;
 79     for(int i = n-2; i >= 0; i--)
 80     {
 81         while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
 82         ch[m++] = p[i];
 83     }
 84     if(n > 1) m--;
 85     ch.resize(m);
 86     return ch;
 87 }
 88
 89 // 多边形的有向面积
 90 double PolygonArea(vector<Point> p)
 91 {
 92     double area = 0;
 93     int n = p.size();
 94     for(int i = 1; i < n-1; i++)
 95         area += Cross(p[i]-p[0], p[i+1]-p[0]);
 96     return area/2;
 97 }
 98
 99 int main()
100 {
101     int T;
102     scanf("%d", &T);
103     while(T--)
104     {
105         int n;
106         double area1 = 0;
107         scanf("%d", &n);
108         vector<Point> P;
109         for(int i = 0; i < n; i++)
110         {
111             double x, y, w, h, j, ang;
112             scanf("%lf%lf%lf%lf%lf", &x, &y, &w, &h, &j);
113             Point o(x,y);
114             ang = -torad(j);
115             P.push_back(o + Rotate(Vector(-w/2,-h/2), ang));
116             P.push_back(o + Rotate(Vector(w/2,-h/2), ang));
117             P.push_back(o + Rotate(Vector(-w/2,h/2), ang));
118             P.push_back(o + Rotate(Vector(w/2,h/2), ang));
119             area1 += w*h;
120         }
121         double area2 = PolygonArea(ConvexHull(P));
122         printf("%.1lf %%\n", area1*100/area2);
123     }
124     return 0;
125 }

时间: 2024-10-22 16:07:20

uva 10652的相关文章

Uva 10652 Board Wrapping

二次联通门 : Virtual Judge Uva 10652 Board Wrapping /* Uva 10652 Board Wrapping 计算几何 将每个家具拆为4个点 对所有点求一个凸包 然后求凸包的面积即可 思路不难.. 但是写起来好麻烦好麻烦 需要注意的东西有很多 1. 角度制转弧度制 2. EPS的选择 3. PI的取值 (以防万一以后还是都写acos(-1)吧...) 4. 在把家具拆成四个点时的细节 4. 计算多边形的面积 */ #include <algorithm>

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

UVA 10652 Board Wrapping 计算几何

多边形凸包.... Board Wrapping Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem B Board Wrapping Input: standard input Output: standard output Time Limit: 2 seconds The small sawmill in Mission, Britis

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&

UVA 10652 Board Wrapping(二维凸包)

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

简单几何(向量旋转+凸包+多边形面积) 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

题意: 有n块互不重叠的矩形木板,用尽量小的凸多边形将它们包起来,并输出并输出木板总面积占凸多边形面积的百分比. 分析: 几乎是凸包和多边形面积的裸题. 注意:最后输出的百分号前面有个空格,第一次交PE了. 用printf打印%,可以连续打印两个%%,printf("%%\n");   这个冷知识记得以前学过,不过不用也就忘了. 学习一下vector容器中去重的小技巧. sort(p.begin(), p.end()); p.erase(unique(p.begin(), p.end(

UVA 10652 凸包问题

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include <iostream> 6 using namespace std; 7 8 const double eps = 1e-10; 9 const int N = 610; 10 int dcmp(double x) 11 { 12 if(abs(x) < e