题意是给定一些矩形,用一条线包围所有的矩形,同时要求包围的面积最小。
思路
凸包
实质就是自己算出所有矩形的四个顶点,求凸包,然后求面积即可。
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
const double eps = 1e-10;
const double PI = 3.1415926535898;
double add(double a, double b){
//if(abs(a + b) < eps * (abs(a) + abs(b))) return 0;
return a + b;
}
struct P{
double x, y;
P(){}
P(double x, double y) : x(x), y(y) {}
P operator + (P p){
return P(add(x, p.x), add(y, p.y));
}
P operator - (P p){
return P(add(x, -p.x), add(y, -p.y));
}
P operator * (double d){
return P(x * d, y * d);
}
double dot(P p){
return add(x * p.x, y * p.y);
}
double det(P p){
return add(x * p.y, -y * p.x);
}
};
bool cmp_x(const P & p, const P & q){
if(p.x != q.x) return p.x < q.x;
return p.y <q.y;
}
vector<P> convex_hull(P* ps, int n){
sort(ps, ps + n, cmp_x);
int k = 0;
vector<P> qs(n * 2);
for(int i = 0; i < n; ++i){
while(k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
qs[k++] = ps[i];
}
for(int i = n - 2, t = k; i >= 0; i --){
while(k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) k--;
qs[k++] = ps[i];
}
qs.resize(k - 1);
return qs;
}
const int maxn = 10000 + 10;
P ps[5 * maxn];
double solve(int cnt, int n){
vector<P> qs = convex_hull(ps, cnt);
double sum = 0.00;
int len = qs.size();
for(int i = 1; i < len - 1; ++i){
sum += (qs[i] - qs[0]).x * (qs[i + 1] - qs[0]).y - (qs[i + 1] - qs[0]).x * (qs[i] - qs[0]).y;
}
sum /= 2.0;
return fabs(sum);
}
void Build(double x, double y, double w, double h, double u, int & cnt){
ps[cnt].x = x - w * cos(u) - h * sin(u);
ps[cnt++].y = y + w * sin(u) - h * cos(u);
ps[cnt].x = x - w * cos(u) + h * sin(u);
ps[cnt++].y = y + w * sin(u) + h * cos(u);
ps[cnt].x = x + w * cos(u) + h * sin(u);
ps[cnt++].y = y - w * sin(u) + h * cos(u);
ps[cnt].x = x + w * cos(u) - h * sin(u);
ps[cnt++].y = y - w * sin(u) - h * cos(u);
}
int main()
{
int T; scanf("%d", &T);
while(T --){
memset(ps, 0, sizeof(ps));
int n; scanf("%d", &n);
int cnt = 0;
double sum = 0;
for(int i = 0; i < n; ++i){
double x, y, u, w, h;
scanf("%lf%lf%lf%lf%lf", &x, &y, &w, &h, &u);
u = u * PI / 180;
sum += w * h;
Build(x, y, w / 2, h / 2, u, cnt);
}
printf("%.1f %%\n", sum * 100 / solve(cnt, n));
}
return 0;
}