您的位置:首页 > 其它

UVA10652【凸包计算】

2016-03-23 11:44 323 查看
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1593

给一些矩形(给定中心(x,y)长w宽h,和旋转角j)

求一个最小多边形把所有的矩形包围,输出矩形所占多边形的面积比。

可以想到是把矩形拆成4个点然后跑凸包。

由于第一次做凸包不是很会,然后看了模板YY一下,就是sort之后每次当前点在凸包最末的那一条边的左边,才能加进来,否则弹掉最后一个点,直到可以加入。

这里还有矩形是旋转的,所以搞点的时候卡了一阵子。

可以看成是每个端点先相对于中心点作原点的向量旋转theta角度之后,把原点平移。

(然而我以为三角函数传入的是360°的角度,没想到竟然是弧度,然后就WA了- -||)

然后处理一下点,就当成裸的凸包吧:

.#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
#define eps 1e-10
const int maxn=620;
const double pi=3.1415926;
using namespace std;
int dcmp(double x)
{
if(fabs(x)<eps)return 0;
else return x<0?-1:1;
}
struct point
{
double x,y;
point(){}
point(double _x,double _y)
{
x=_x;
y=_y;
}
point operator +(const point &b)
{
return point(x+b.x,y+b.y);
}
point operator -(const point &b)
{
return point(x-b.x,y-b.y);
}
point operator *(const double &b)
{
return point(x*b,y*b);
}
}p[4*maxn];
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
int n;
int cnt;
point rotate(point a,double rad)
{
//cout<<a.x*cos(rad)<<" "<<a.y*sin(rad)<<" "<<endl;
return point(a.x*cos(rad)+a.y*sin(rad),a.y*cos(rad)-a.x*sin(rad));
}
bool cmp(point x,point y)
{
if(x.x!=y.x)return x.x<y.x;
else return x.y<y.y;
}
point q[4*maxn];
double ans1,ans2;
void solve()
{
sort(p+1,p+cnt+1,cmp);
int m=0;
for(int i=1;i<=cnt;i++)
{
while(m>1&&dcmp(cross(q[m-1]-q[m-2],p[i]-q[m-2]))<=0)m--;
q[m++]=p[i];
}
int k=m;
for(int i=cnt-1;i>=1;i--)
{
while(m>k&&dcmp(cross(q[m-1]-q[m-2],p[i]-q[m-2]))<=0)m--;
q[m++]=p[i];
}
if(cnt>1)m--;

for(int i=0;i<m-1;i++)ans2+=cross(q[i]-q[0],q[i+1]-q[0]);
ans2=0.5*fabs(ans2);
printf("%.1f %\n",ans1/ans2);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cnt=0;
ans1=ans2=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
double x,y,w,h,j;
scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&j);
ans1+=w*h*100;
j=j/180*pi;
//cout<<rotate(point(-w/2,h/2),j).x<<" "<<rotate(point(-w/2,h/2),j).y<<endl;
p[++cnt]=rotate(point(-w/2,h/2),j)+point(x,y);
p[++cnt]=rotate(point(w/2,h/2),j)+point(x,y);
p[++cnt]=rotate(point(-w/2,-h/2),j)+point(x,y);
p[++cnt]=rotate(point(w/2,-h/2),j)+point(x,y);
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  几何 uva 凸包