题意:
有n个小矩形,求把他们包起来的最小多边形,并计算出这些矩形面积占总凸包面积的百分比。
求最小凸包,然后在处理即可。
代码:
#include <iostream> #include <cmath> #include <cstdio> #include <algorithm> using namespace std; const double eps = 1e-10; 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 -(Vector A, Vector 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); } int dcmp(double x){//精度控制 if(fabs(x) < eps) return 0; return x < 0 ? -1 : 1; } bool operator ==(const Point &a, const Point &b){ return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; } double Dot(Vector A, Vector B){//点乘 return A.x*B.x + A.y*B.y; } double length(Vector A){ return sqrt(Dot(A, A)); } double Angle(Vector A, Vector B){//向量夹角 return acos(Dot(A, B) / length(A) / length(B)); } double Cross(Vector A, Vector B){//叉积 return A.x*B.y - A.y*B.x; } double torad(double deg){//角度化弧度 return deg/180 * acos(-1.0); } 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 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; } 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 && dcmp (Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])) != 1) m--; ch[m++] = p[i]; } int k = m; for(int i = n - 2; i >= 0; i--) { while(m > k && dcmp (Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])) !=1) m--; ch[m++] = p[i]; } if(n > 1) m--; return m; } int main(){ int T; Point P[2500], ch[2500]; cin >> T; while(T--){ int n, pc = 0; double area1 = 0; cin >> 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); area1 += w*h; } int m = ConvexHull(P, pc, ch); double area2 = PolygonArea(ch, m); printf("%.1f %%\n", area1*100/area2); } return 0; }