传送门
题意:给
n
n
n个
A
∗
B
A*B
A∗B的矩形,其中每个矩形的四个角被改造成了半径为
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;
}