题意
通过观察发现答案为一个整圆+所有除去圆弧的四个顶点形成的凸包的周长,于是直接套模板就好了。
code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=10010;
const double eps=1e-8;
const double Pi=acos(-1.0);
int n,tot,top;
int sta[maxn];
double H,L,R,ans;
struct Point{
double x,y;
Point operator+(const Point& a)const{return (Point){x+a.x,y+a.y};}
Point operator-(const Point& a)const{return (Point){x-a.x,y-a.y};}
Point operator*(const double& k){return (Point){x*k,y*k};}
Point operator/(const double& k){return (Point){x/k,y/k};}
double operator*(const Point& a)const{return x*a.y-y*a.x;}
double operator&(const Point& a)const{return x*a.x+y*a.y;}
}p[maxn<<2];
inline int dcmp(double x)
{
if(fabs(x)<=eps)return 0;
return x<0?-1:1;
}
inline Point turn(Point a,double theta){return (Point){a.x*cos(theta)-a.y*sin(theta),a.x*sin(theta)+a.y*cos(theta)};}
inline double dis(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
inline bool cmp(Point a,Point b){return a.x==b.x?a.y<b.y:a.x<b.x;}
int main()
{
scanf("%d%lf%lf%lf",&n,&H,&L,&R);
for(int i=1;i<=n;i++)
{
double x,y,theta;scanf("%lf%lf%lf",&x,&y,&theta);
x+=eps,y+=eps,theta+=eps;
double tmpx=L-2*R,tmpy=H-2*R;
p[++tot]=turn((Point){-tmpx/2.0,tmpy/2.0},theta)+(Point){x,y};
p[++tot]=turn((Point){tmpx/2.0,tmpy/2.0},theta)+(Point){x,y};
p[++tot]=turn((Point){tmpx/2.0,-tmpy/2.0},theta)+(Point){x,y};
p[++tot]=turn((Point){-tmpx/2.0,-tmpy/2.0},theta)+(Point){x,y};
}
sort(p+1,p+tot+1,cmp);
for(int i=1;i<=tot;i++)
{
while(top>1&&dcmp((p[sta[top]]-p[sta[top-1]])*(p[i]-p[sta[top]]))<=0)top--;
sta[++top]=i;
}
int tmp=top;
for(int i=tot-1;i;i--)
{
while(top>tmp&&dcmp((p[sta[top]]-p[sta[top-1]])*(p[i]-p[sta[top]]))<=0)top--;
sta[++top]=i;
}
for(int i=1;i<top;i++)ans+=dis(p[sta[i]].x,p[sta[i]].y,p[sta[i+1]].x,p[sta[i+1]].y);
printf("%.2lf",ans+2*Pi*R);
return 0;
}