首页 > 代码库 > UVA 10652 凸包问题

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 10652 凸包问题