UVA10652 Board Wrapping(凸包)

这篇博客探讨了如何使用计算几何的方法找到一个最小的多边形来包含给定的多个矩形,并计算这些矩形在这个多边形中占据的百分比。程序实现了凸包算法(Convex Hull)来找到包围矩形的最小多边形,并通过计算多边形和矩形总面积来得出占比。
摘要由CSDN通过智能技术生成

 

Sample Input
1
4
4 7.5 6 3 0
8 11.5 6 3 0
9.5 6 6 3 90
4.5 3 4.4721 2.2361 26.565
Sample Output
64.3 %

有 n 个矩形,求一个面积最小的多边形可以包含这 n 个矩形,输出这 n 个矩形占这个 n 边形的百分比 

const int N=3e3+5;

    int i,j,k;
    int n,m,t;
    struct Point
    {
        double x,y;
        Point(double x=0,double y=0):x(x),y(y){}
        bool operator<(Point o)
        {
            return (o.x!=x)?x<o.x:y<o.y;
        }
    }p[N],ch[N];
    typedef Point Vector;
    Vector operator+(Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y); }
    Vector operator-(Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y); }
    double Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }

double torad(double x)
{
    return x/180*pi;
}

Vector rotate(Vector a,double rad)
{
    return Vector(a.x*cos(rad)-a.y*sin(rad),a.y*cos(rad)+a.x*sin(rad));
}

int ConvexHull(Point *p,int n,Point *ch)
{
    sort(p,p+n);
    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];
    }
    if(n>1) m--;
    return m;
}
 
double PolygonArea(Point *p,int n)
{
    double ans=0;
    for(int i=1;i<=n-1;i++){
        ans+=Cross(p[i]-p[0],p[i+1]-p[0]);
    }
    return ans/2;
}

int main()
{
    //IOS;
    rush(){
        sd(n); m=0;
        double x,y,h,w,rad,area=0;
        for(int i=0;i<n;i++){
            sff(x,y);
            sfff(w,h,rad);
            rad=-torad(rad);
            Point o(x,y);
            p[m++]=o+rotate(Vector(w/2,h/2),rad);
            p[m++]=o+rotate(Vector(w/2,-h/2),rad);
            p[m++]=o+rotate(Vector(-w/2,h/2),rad);
            p[m++]=o+rotate(Vector(-w/2,-h/2),rad);
            area+=w*h;
        }
        int vex=ConvexHull(p,m,ch);
        double ans=PolygonArea(ch,vex);
        printf("%.1lf %%\n",area*100/ans);
    }
    //PAUSE;
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值