题目大意:
给定一些矩形,要求用面积最小的凸多边形覆盖这些矩形,求所有矩形占凸包面积百分比。
题目分析:
很显然就是把所有的矩形的顶点放在一起做个凸包求个面积就好了(本来这道题就是拿来写板子的啊)。
这个题唯一恶心的地方就是给矩形的方式丧心病狂,它给出了矩形的中心坐标,长,宽,和倾斜角(而且还TM是角度制)。
所以要把这个东西转成弧度制,再用数学知识推导(倒)这个矩形四个顶点的坐标。
其实本来没想总结一个板子的QAQ
但是昨天有个学长跟我讲:
说实话
你比赛是不是经常崩
你的代码有很大问题
首先你的凸包算法写的不是一个函数
很不好维护
导致了你的凸包的大小top没有初始化……
于是今天我把它写成了一个函数
代码如下:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define EPS 1e-8
#define N 10000
const double pi=acos(-1);
int cmp(double x)
{
if(fabs(x)<EPS) return 0;
if(x>0) return 1;
return -1;
}
double to_rad(double x)
{
return pi*x/180.0;
}
struct point{
double x,y;
point(double a=0,double b=0): x(a), y(b) {}
bool operator < (const point &c) const { return cmp(x-c.x)<0 || (cmp(x-c.x)==0 && cmp(y-c.y)<0); }
point operator + (const point &c) const { return point(x+c.x,y+c.y); }
point operator - (const point &c) const { return point(x-c.x,y-c.y); }
friend double det(const point &a,const point &b) { return a.x*b.y-a.y*b.x;}
}a[N],P[N];
int T,n,tot;
double x,y,w,h,fi;
double ans,sum;
void read()
{
scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&fi);
fi=to_rad(90.0-fi);
point t=point(x,y);
point t1=point(h*cos(fi)/2.0,h*sin(fi)/2.0);
point t2=point(-t1.y*w/h,t1.x*w/h);
a[++tot]=t+t1+t2;
a[++tot]=t+t1-t2;
a[++tot]=t-t1+t2;
a[++tot]=t-t1-t2;
sum+=w*h;
}
int convex_hull(point a[],point P[],int tot)
{
sort(a+1,a+1+tot);
int top=0;
for(int i=1;i<=tot;++i)
{
while(top>1 && cmp(det(P[top]-P[top-1],a[i]-P[top-1]))<=0) --top;
P[++top]=a[i];
}
int k=top;
for(int i=tot-1;i>=1;--i)
{
while(top>k && cmp(det(P[top]-P[top-1],a[i]-P[top-1]))<=0) --top;
P[++top]=a[i];
}
return top-1;
}
int main()
{
scanf("%d",&T);
while(T--)
{
sum=tot=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) read();
int top=convex_hull(a,P,tot);
ans=0;
point O(0.0,0.0);
for(int i=1;i<=top;i++)
ans+=det(P[i]-O,P[i%top+1]-O);
ans/=2.0;
if(ans!=0) ans=sum/ans*100.0;
printf("%.1lf %%\n",ans);
}
return 0;
}