bzoj2829: 信用卡凸包(凸包)

该博客探讨了如何解决一个计算几何问题——给定带有圆形角的矩形,计算它们的凸包周长。文章介绍了问题背景,提出了通过求解圆心的凸包周长并加上完整圆周长的思路,并省略了证明细节,同时提供了相关代码实现。
摘要由CSDN通过智能技术生成

传送门
题意:给 n n n A ∗ B A*B AB的矩形,其中每个矩形的四个角被改造成了半径为 r r r的四分之一 圆,问这些矩形的凸包周长。


思路:考虑求出圆心的凸包周长然后加上一个整圆的周长,证明很简单,略掉。
代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=10005;
struct pot{
    double x,y;
    friend inline pot operator+(const pot&a,const pot&b){return (pot){a.x+b.x,a.y+b.y};}
    friend inline pot operator-(const pot&a,const pot&b){return (pot){a.x-b.x,a.y-b.y};}
    friend inline double operator^(const pot&a,const pot&b){return a.x*b.y-a.y*b.x;}
    friend inline bool operator<(const pot&a,const pot&b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    inline double mod(){return sqrt(x*x+y*y);}
}a[N<<2];
int n,tot=0,q[N<<2],top=0;
double A,B,R,ans,a1,a2,a3,a4,D;
const double pi=acos(-1.0),eps=1e-8;
inline void graham(){
    n=tot;
    sort(a+1,a+n+1);
    q[++top]=1;
    for(ri i=2;i<=n;++i){
        while(top>1&&((a[q[top]]-a[q[top-1]])^(a[i]-a[q[top-1]]))<=0)--top;
        q[++top]=i;
    }
    for(ri lim=top,i=n-1;i;--i){
        while(top>lim&&((a[q[top]]-a[q[top-1]])^(a[i]-a[q[top-1]]))<=0)--top;
        q[++top]=i;
    }
    for(ri i=1;i<top;++i)ans+=(a[q[i]]-a[q[i+1]]).mod();
}
int main(){
    scanf("%d%lf%lf%lf",&n,&A,&B,&R);
    A=A/2-R,B=B/2-R;
    a1=atan(A/B),a2=pi-a1,a3=pi+a1,a4=-a1;
    D=sqrt(A*A+B*B);
    ans=R*pi*2.0;
    for(ri i=1;i<=n;++i){
        double x,y,theta;
        scanf("%lf%lf%lf",&x,&y,&theta);
        a[++tot]=(pot){cos(theta+a1)*D+x,sin(theta+a1)*D+y};
        a[++tot]=(pot){cos(theta+a2)*D+x,sin(theta+a2)*D+y};
        a[++tot]=(pot){cos(theta+a3)*D+x,sin(theta+a3)*D+y};
        a[++tot]=(pot){cos(theta+a4)*D+x,sin(theta+a4)*D+y};
    }
    graham();
    printf("%.2lf",ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值