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 }
View Code

 

posted @ 2015-10-14 23:20  yyblues  阅读(236)  评论(0编辑  收藏  举报