UVA 10652 - Board Wrapping 简单计算几何 凸包

本文详细介绍了如何通过求解凸包问题来优化几何问题的解决方案,利用刘汝佳的模版简化了计算过程,并提供了代码实现。通过旋转函数和角度转换的正确使用,避免了常见的错误,确保了算法的准确性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题是一个简单的凸包问题

关键的一点就是   把每个块的四个顶点都求出来   最后排序求凸包      求的时候涉及到角度旋转   因为计算机上的三角函数都是弧度制的  转换的时候注意一点    自己写的旋转的函数的角度参数是正的  还是负的 也要注意      否者很容易出错     

下面看代码  用的是刘汝佳的模版   本人感觉用着不错   比自己写的好多了   计算几何模版需要高度可靠    

#include<cstdio>
#include<cmath>
#include<algorithm>
#define eps 1e-8
using namespace std;

struct Point
{
    double x,y;
    Point (double x = 0,double y = 0):x(x),y(y){}
};

typedef struct 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);
}

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

double Cross(Vector A, Vector B)
{
    return A.x*B.y -A.y*B.x;
}

double PolygonArea(Point *p, int n)
{
    double area = 0;
    for(int i = 0 ; i < n-1; i++)
        area += Cross(p[i] - p[0], p[i+1] - p[0]);
    return area / 2;
}

int cmp(Point a,Point b)
{
    if(a.x<b.x)return 1;
    else if(a.x == b.x && a.y < b.y)return 1;
    return 0;
}

int ConvexHull(Point *s,int n,Point *ch)
{
    sort(s,s+n,cmp);
    int m = 0;
    for(int i = 0; i < n; i++)
    {
        while(m >1 && Cross(ch[m-1]-ch[m-2],s[i]-ch[m-2])<= 0)m--;
        ch[m++] = s[i];
    }
    int k = m;
    for(int i = n-2; i >=0; i--)
    {
        while(m > k && Cross(ch[m-1]-ch[m-2],s[i]-ch[m-2]) <= 0)m--;
        ch[m++] = s[i];
    }
    if(n>1)m--;
    return m;
}

int main()
{
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    #endif // LOCAL
    int T;
    Point p[2500],ch[2500];
    scanf("%d",&T);
    while(T--)
    {
        int n, pc = 0;
        double area1 = 0;
        scanf("%d",&n);
        for(int i = 0; i <n; i++)
        {
            double x,y,w,h,ang,j;
            scanf("%lf%lf%lf%lf%lf",&x,&y,&w,&h,&j);
            Point o(x,y);
            ang = -j*acos(-1)/180.0;//逆时针的角度
            p[pc++] = o + Rotate(Vector(-w/2,-h/2),ang);//因为Rotate函数的ang是逆时针的
            p[pc++] = o + Rotate(Vector(w/2,-h/2),ang);
            p[pc++] = o + Rotate(Vector(-w/2,h/2),ang);
            p[pc++] = o + Rotate(Vector(w/2,h/2),ang);
            area1 += w*h;
        }
        int m = ConvexHull(p,pc,ch);
        double area2 = PolygonArea(ch,m);
        printf("%.1lf %%\n",area1*100/area2);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值