#include <bits/stdc++.h> using namespace std; const double PI = acos(-1.0); struct Point { double x, y; Point(double x = 0, double y = 0): x(x), y(y) {} }; typedef Point Vector; Vector operator +(Vector A, Vector B)// { return Vector(A.x + B.x, A.y + B.y); } Vector operator -(Point A, Point B)// { return Vector(A.x - B.x , A.y - B.y); } Vector operator *(Vector A, double p)// { return Vector(A.x * p, A.y * p); } Vector operator /(Vector A, double p)// { return Vector(A.x / p, A.y / p); } bool operator <(const Point &a, const Point &b)// { return a.x < b.x || (a.x == b.x && a.y < b.y); } double Cross(Vector A, Vector B)// { return A.x * B.y - A.y * B.x; } double PolygonArea(Point *p, int n) // { double area = 0; for (int i = 1; i < n - 1; i++) area += Cross(p[i] - p[0], p[i + 1] - p[0]); return area / 2; } Vector Rotate(Vector A, double rad) // { return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad)); } double torad(double deg) { return deg / 180 * PI; } int ConvexHull(Point*p, int n, Point *ch) { sort(p, p + n); int m = 0; for (int i = 0; i < n; i++) { while (m > 1 && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m--; ch[m++] = p[i]; } int k = m; for (int i = n - 2; i >= 0; i--) { while (m > k && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m--; ch[m++] = p[i]; } if (n > 1) m--; return m; } int main(int argc, char const *argv[]) { int T; Point P[2500], ch[2500]; scanf("%d", &T); while (T--) { int n, pc = 0; double areal = 0; scanf("%d", &n); for (int i = 0; i < n; i++) { double x, y, w, h, j, ang; scanf("%lf%lf%lf%lf%lf", &x, &y, &w, &h, &j); Point o(x, y); ang = -torad(j); P[pc++] = o + Rotate(Vector(-w / 2, -h / 2), ang); P[pc++] = o + Rotate(Vector(w / 2, -h / 2), ang); P[pc++] = o + Rotate(Vector(-w / 2, h / 2), ang); P[pc++] = o + Rotate(Vector(w / 2, h / 2), ang); areal += w * h; } int m = ConvexHull(P, pc, ch); double area2 = PolygonArea(ch, m); printf("%.1lf %%\n", areal * 100 / area2); } return 0; }
大意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们包起来,并计算出木板站整个包装面积的百分比。
思路:按照题意将所有矩形顶点坐标存起来,旋转时先旋转从中心出发的向量,求得各个坐标之后,求凸包即可。