大意:有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 }
时间: 2024-10-22 16:07:20