题意:给出n个矩形的中间点坐标,相对Y轴的偏转度数,求所有矩形的面积和与围住这些矩形的最小凸包的面积比。
思路:处理出所有的点,然后求个凸包,最后算面积。
struct point {
double x, y;
point() {}
point(double x,double y) {
this->x = x;
this->y = y;
}
bool operator < (const point& rhs) const {
return x < rhs.x || (x == rhs.x && y < rhs.y);
}
point operator - (const point& rhs) {
return point(x - rhs.x, y - rhs.y);
}
point operator + (const point& rhs) {
return point(x + rhs.x, y + rhs.y);
}
}p[12345], buff[12345];
int n, m;
double torad(double ang) {
double rad = ang * pi / 180;
if (dcmp(rad) < 0) rad += 2*pi;
return rad;
}
point rotate(point a, double rad) {
return point(a.x*cos(rad) - a.y*sin(rad), a.x * sin(rad) + a.y*cos(rad));
}
double Cross(point a,point b) {
return a.x*b.y - a.y*b.x;
}
int getConvexHull(point* p, int num, point* buff) {
sort(p, p + num);
// for (int i = 0;i < num;++i)
// printf("(%.2lf, %.2lf)\n", p[i].x, p[i].y);
int top = 0;
for (int i = 0;i < num;++i) {
while(top > 1 && dcmp(Cross(buff[top - 1] - buff[top - 2], p[i] - buff[top - 1])) <= 0)
top--;
buff[top++] = p[i];
}
int k = top;
for (int i = num - 2;i >= 0;--i) {
while(top > k && dcmp(Cross(buff[top - 1] - buff[top - 2], p[i] - buff[top - 2])) <= 0)
top--;
buff[top++] = p[i];
}
if (num > 1) top--;
return top;
}
double getArea(point* p, int num) {
double ans = 0;
for (int i = 1;i < num - 1;++i)
ans += Cross(p[i] - p[0], p[i+1] - p[0]);
return fabs(ans) / 2;
}
int main(int argc, const char * argv[])
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t;
cin >> t;
while(t--) {
scanf("%d", &n);
m = 0;
double x, y, w, h, j;
double area1 = 0.0, area2;
for (int i = 0;i < n;++i) {
scanf("%lf %lf %lf %lf %lf", &x, &y, &w, &h, &j);
point temp(x, y);
double rad = -torad(j);
p[m++] = temp + rotate(point(-w/2, -h/2), rad);
p[m++] = temp + rotate(point(-w/2, h/2), rad);
p[m++] = temp + rotate(point( w/2, -h/2), rad);
p[m++] = temp + rotate(point( w/2, h/2), rad);
area1 += w*h;
}
// printf("area1 = %.12lf\n", area1);
int num = getConvexHull(p, m, buff);
// cout << "num = " << num << endl;
area2 = getArea(buff, num);
printf("%.1lf %%\n", area1*100.0 / area2);
}
return 0;
}