直接上代码
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int n;
struct the_point{
double x,y;
}point[400005],ans[400005];
const double Pi = 3.141592653589793;
bool cmp(the_point x,the_point y){
if(x.x == y.x)
return x.y < y.y;
return x.x < y.x;
}
double cross(the_point a,the_point b){
return a.x*b.y - a.y*b.x;
}
the_point operator - (the_point a,the_point b){
the_point ans;
ans.x = a.x - b.x;
ans.y = a.y - b.y;
return ans;
}
int convex_hull(the_point* p,the_point* ch){
sort(p,p+n*4,cmp);
int m = 0;
for(int i=0;i<n*4;i++){
while(m>1 and 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*4 - 2;i>=0;i--){
while(m>k and cross(ch[m-1] - ch[m-2],p[i] - ch[m-2])<=0)m--;
ch[m++] = p[i];
}
if(n*4 > 1)m--;
return m;
}
double get_len(the_point a){
return sqrt(a.x*a.x + a.y*a.y);
}
int main(){
double a,b,r,x,y,angle_b,angle_a,len_;
scanf("%d",&n);
scanf("%lf%lf%lf",&a,&b,&r);
len_ = sqrt(a*a + b*b)/2 - sqrt(r*r*2);
angle_a = atan(a/b);
for(int i=0;i<n;i++){
scanf("%lf%lf%lf",&x,&y,&angle_b);
point[i*4].x = x + len_*(cos(angle_a + angle_b));
point[i*4].y = y + len_*(sin(angle_a + angle_b));
point[i*4+1].x = x - len_*(cos(angle_a + angle_b));
point[i*4+1].y = y - len_*(sin(angle_a + angle_b));
point[i*4+2].x = x + len_*(cos(-angle_a + angle_b));
point[i*4+2].y = y + len_*(sin(-angle_a + angle_b));
point[i*4+3].x = x - len_*(cos(-angle_a + angle_b));
point[i*4+3].y = y - len_*(sin(-angle_a + angle_b));
}
int num = convex_hull(point,ans);
double ans_num = 0;
for(int i=0;i<num;i++){
ans_num += get_len(ans[i+1] - ans[i]);
}
// ans_num += get_len(point[0] - ans[num-1]);
ans_num += Pi*r*2;
printf("%.2lf",ans_num);
return 0;
}