题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1593
把每个矩形的四个顶点都找出来,做凸包就是最小的多边形,计算面积就从一个点出发向每个点都连一条对角线,将多边形分成若干个三角形再计算。
比较坑的是,数字和“%”之间还有一个空格>_<!
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct Point
{
double x, y;
Point() {};
Point(double x, double y):x(x), y(y) {}
bool operator < (const Point& a) const
{
if (x == a.x)
return y < a.y;
return x < a.x;
}
bool operator == (const Point& a) const
{
if (x == a.x && y == a.y)
return true;
return false;
}
};
typedef Point Vector;
Point P[2500], convex[2500];
Vector operator - (const Point& A, const Point& B)
{
return Vector(A.x-B.x, A.y-B.y);
}
Point operator + (const Point& A, const Vector& a)
{
return Point(A.x+a.x, A.y+a.y);
}
double Cross(Vector A, Vector B)
{
return A.x*B.y - A.y*B.x;
}
double Area( Point A, Point B, Point C)
{
return Cross(A-B, A-C) / 2;
}
Vector Rotate(const Vector& A, double rad) //顺时针旋转向量A
{
return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
int ConvexHull(Point* p, int n, Point* ch)
{
sort(p, p+n);
n = unique(p, p+n) - p;
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];
}
return m;
}
int main()
{
int T;
scanf("%d",&T);
while (T > 0)
{
T--;
int n;
double RecArea = 0;
scanf("%d",&n);
int cnt = 0;
for (int i=0; i<n; i++)
{
double x, y, w, h, j;
scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&j);
RecArea += w*h;
Point centre(x,y);
Vector v1(w/2,h/2), v2(w/2,-h/2), v3(-w/2, h/2), v4(-w/2,-h/2);
Point p1 = centre + Rotate(v1,-j/180*3.1415926);
Point p2 = centre + Rotate(v2,-j/180*3.1415926);
Point p3 = centre + Rotate(v3,-j/180*3.1415926);
Point p4 = centre + Rotate(v4,-j/180*3.1415926);
P[cnt++] = p1; P[cnt++] = p2; P[cnt++] = p3; P[cnt++] = p4;
}
n = ConvexHull(P,cnt,convex);
double ConvexArea = 0;
for (int i=1; i<n-1; i++)
ConvexArea += Area(convex[0],convex[i],convex[i+1]);
double ans = RecArea / ConvexArea * 100;
printf("%.1lf ",ans);
cout << '%' << endl;
}
return 0;
}