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 }