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 }

 

你可能感兴趣的:(uva)