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) < eps) return 0;
 13     if(x < 0) return -1;
 14     else return 1;
 15 }
 16
 17 struct Point{
 18     double x,y;
 19     Point(double x = 0,double y = 0):x(x),y(y){}
 20     bool operator<(const Point &m)const{
 21         return dcmp(x - m.x) < 0 || (dcmp(x - m.x) == 0 && dcmp(y - m.y) < 0);
 22     }
 23
 24     bool operator==(const Point &m)const{
 25         return dcmp(x - m.x) == 0 && dcmp(y - m.y) == 0;
 26     }
 27 };
 28
 29 Point ch[N<<2],p[N<<2];
 30
 31 typedef Point Vector;
 32
 33 Vector operator+(Vector a , Vector b)
 34 {
 35     return Vector(a.x + b.x , a.y + b.y);
 36 }
 37
 38 Vector operator-(Point a , Point b)
 39 {
 40     return Vector(a.x - b.x , a.y - b.y);
 41 }
 42
 43 Vector operator*(Vector a , double b)
 44 {
 45     return Vector(a.x * b , a.y * b);
 46 }
 47
 48 Vector operator/(Vector a , double b)
 49 {
 50     return Vector(a.x / b , a.y/b);
 51 }
 52
 53 double Cross(Vector a , Vector b)
 54 {
 55     return a.x * b.y - a.y * b.x;
 56 }
 57
 58 Vector GetReverse(Vector a , double rad)
 59 {
 60     double x = a.x * cos(rad) - a.y * sin(rad);
 61     double y = a.x * sin(rad) + a.y * cos(rad);
 62     return Vector(x,y);
 63 }
 64 //计算多边形面积
 65 double ConvexPolygonArea(Point *p , int n)
 66 {
 67     double area = 0;
 68     for(int i=1;i<n-1;i++){
 69         area += Cross(p[i] - p[0] , p[i+1] - p[0]);
 70     }
 71     return area / 2;
 72 }
 73 //求形成凸包的最大范围
 74 int ConvexHull(Point *p, int n, Point *ch) //凸包
 75 {
 76     sort(p, p+n);
 77     n = unique(p, p+n) - p; //去重
 78     int m = 0;
 79     for(int i = 0; i < n; i++)
 80     {
 81         while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
 82         ch[m++] = p[i];
 83     }
 84     int k = m;
 85     for(int i = n-2; i >= 0; i--)
 86     {
 87         while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
 88         ch[m++] = p[i];
 89     }
 90     if(n > 1) m--;
 91     return m;
 92 }
 93 int main()
 94 {
 95   //  freopen("test.in","rb",stdin);
 96
 97     int T,n;
 98     double x,y,w,h,_angle; //_angle表示度数,自己还要转化成弧度
 99     scanf("%d",&T);
100     while(T--){
101         scanf("%d",&n);
102         int k=0;
103         double area = 0;
104         for(int i=0;i<n;i++)
105         {
106             scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&_angle);
107             area += w*h;
108             double rad = -_angle * acos(-1) / 180;
109             Point o(x,y);
110             //cout<<"  rad:  "<<rad<<endl;
111             p[k++] = GetReverse(Vector(-w/2 , h/2),rad) + o;
112             p[k++] = GetReverse(Vector(w/2 , h/2),rad) + o;
113             p[k++] = GetReverse(Vector(w/2 , -h/2),rad) + o;
114             p[k++] = GetReverse(Vector(-w/2 , -h/2),rad) + o;
115         }
116
117         int m = ConvexHull(p , k , ch);
118         double sumOfArea = ConvexPolygonArea(ch , m);
119         double ans = area / sumOfArea * 100;
120
121         printf("%.1f %%\n",ans);
122     }
123     return 0;
124 }
时间: 2024-08-02 01:34:20

UVA 10652 凸包问题的相关文章

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

二次联通门 : 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(凸包)

题目链接: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 Board Wrapping(计算几何基础,求凸包)

题目链接:传送门 分析: 没有什么好说的就是求一个凸包就好了.可以当作模板. 代码如下: #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const double eps = 1e-10; //判断符号,提高精度 int dcmp(double x){ if(fab

uva 10652

大意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们包起来,并计算出木板站整个包装面积的百分比. 思路:按照题意将所有矩形顶点坐标存起来,旋转时先旋转从中心出发的向量,求得各个坐标之后,求凸包即可. 水.... 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 #include<