Uva 10652 Board Wrapping(计算几何之凸包+点旋转)

  题目大意:给出平面上许多矩形的中心点和倾斜角度,计算这些矩形面积占这个矩形点形成的最大凸包的面积比。

  算法:GRAHAM,ANDREW。

  题目非常的简单,就是裸的凸包 + 点旋转。这题自己不会的地方就是点旋转,另外,Andrew 算法还没有调试出来 。有一个非常细节的地方:给出的矩形有N个,但是点有4*N个。

  直接上代码:GRAHAM

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cmath>
 7 
 8 using namespace std;
 9 
10 int N,pc,top;
11 double Tot_s = 0,area = 0;
12 
13 struct data{
14     double x,y;
15     
16     data(double x=0,double y=0):x(x),y(y) {}
17 };
18 data pt[2500],st[2500];
19 double cross(data a,data b,data td){
20     return (a.x-td.x)*(b.y-td.y) - (a.y-td.y)*(b.x-td.x);
21 }
22 double dis(data a,data b){
23     return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
24 }
25 bool cmp(data a,data b){
26     if(cross(a,b,pt[0]) == 0)
27         return dis(a,pt[0]) < dis(b,pt[0]);
28     return cross(a,b,pt[0]) > 0;
29 }
30 data Rotate(data a,double rad){
31     return data(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
32 }
33 data operator + (data a,data b){
34     return data(a.x+b.x,a.y+b.y);
35 }
36 double torad(double deg){
37     return deg/180*acos(-1);//acos(-1) = PI
38 }
39 void Graham(){
40     int k = 0;data tp;
41     top = 2;
42     for(int i = 1;i < 4*N;++ i)
43         if(pt[k].x>pt[i].x || (pt[k].x==pt[i].x&&pt[k].y>pt[i].y))
44             k = i;
45     tp = pt[k];pt[k] = pt[0];pt[0] = tp;
46     sort(pt+1,pt+4*N,cmp);
47     st[0] = pt[0];st[1] = pt[1];st[2] = pt[2];
48     for(int i = 3;i < 4*N;++ i){
49         while(top && cross(pt[i],st[top],st[top-1]) >= 0)
50             top --;
51         st[++ top] = pt[i];
52     }    
53     st[++ top] = pt[0];
54     for(int i = 0;i < top;++ i)
55         Tot_s += cross(st[0],st[i],st[i+1]);
56     Tot_s /= 2;
57 }
58 void init(){
59     scanf("%d",&N);
60     for(int i = 0;i < N;++ i){
61         double x,y,w,h,j,ang;
62         
63         scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&j);
64         
65         data cen(x,y);
66         ang = -torad(j);
67         pt[pc ++] = cen + Rotate(data(-w/2,-h/2),ang);
68         pt[pc ++] = cen + Rotate(data(w/2,h/2),ang);
69         pt[pc ++] = cen + Rotate(data(-w/2,h/2),ang);
70         pt[pc ++] = cen + Rotate(data(w/2,-h/2),ang);
71         area += w*h;
72     }
73     Graham();
74     pc = 0;
75     
76 }
77 
78 int main(){
79     int tcase;
80     scanf("%d",&tcase);
81     while(tcase --){
82         init();
83         printf("%.1lf ",area*100/Tot_s);
84         cout << "%" << endl;
85         area = 0;Tot_s = 0;
86     }
87     
88     return 0;
89 }
View Code

 

posted @ 2015-08-10 11:23  漫步者。!~  阅读(264)  评论(0编辑  收藏  举报