这道题是水题,发现平移某些边,答案就是圆心的凸包+一个圆的周长。
不要忽视精度误差!
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 const int N=100010; 8 const double eps=1e-8; 9 const double Pi=acos(-1.0); 10 int sgn(double x){ 11 if(x>eps)return 1; 12 if(x<-eps)return -1; 13 return 0; 14 } 15 struct Point{ 16 double x,y; 17 Point(double _=0,double __=0){x=_;y=__;} 18 friend Point operator+(Point a,Point b){ 19 return Point(a.x+b.x,a.y+b.y); 20 } 21 friend Point operator-(Point a,Point b){ 22 return Point(a.x-b.x,a.y-b.y); 23 } 24 friend bool operator<(Point a,Point b){ 25 return sgn(a.y-b.y)?sgn(b.y-a.y)>0:sgn(b.x-a.x)>0; 26 } 27 }st[4*N],p[4*N]; 28 double Cross(Point a,Point b){ 29 return a.x*b.y-a.y*b.x; 30 } 31 32 Point Rotate(Point a,double th){ 33 double s=sin(th),c=cos(th); 34 return Point(a.x*c-a.y*s,a.x*s+a.y*c); 35 } 36 37 double sqr(double x){return x*x;} 38 double Dis(Point a,Point b){ 39 return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); 40 } 41 42 bool cmp(Point a,Point b){ 43 double c=Cross(a-p[0],b-p[0]); 44 if(sgn(c)>0)return true; 45 if(sgn(c)<0)return false; 46 return sgn(Dis(p[0],b)-Dis(p[0],a))>0; 47 } 48 49 double a,b,r; 50 double x,y,th; 51 int n,pos,top,tot; 52 int main(){ 53 freopen("card.in","r",stdin); 54 freopen("card.out","w",stdout); 55 scanf("%d",&n); 56 scanf("%lf%lf%lf",&b,&a,&r); 57 a=a/2.0;a=a-r;b=b/2.0;b=b-r; 58 for(int i=1;i<=n;i++){ 59 scanf("%lf%lf%lf",&x,&y,&th); 60 Point O(x,y); 61 p[i*4-4]=Rotate(Point(x+a,y+b)-O,th)+O; 62 p[i*4-3]=Rotate(Point(x+a,y-b)-O,th)+O; 63 p[i*4-2]=Rotate(Point(x-a,y+b)-O,th)+O; 64 p[i*4-1]=Rotate(Point(x-a,y-b)-O,th)+O; 65 } 66 sort(p,p+4*n); 67 for(int i=0;i<4*n;i++){ 68 if(i==0)p[tot++]=p[i]; 69 else if(sgn(p[i].x-p[i-1].x)||sgn(p[i].y-p[i-1].y)) 70 p[tot++]=p[i]; 71 } 72 sort(p+1,p+tot,cmp);p[tot]=p[0]; 73 st[1]=p[0];st[2]=p[1];top=2; 74 for(int i=2;i<=tot;i++){ 75 while(top>=2&&sgn(Cross(st[top]-p[i],st[top-1]-p[i]))>=0)top--; 76 st[++top]=p[i]; 77 } 78 double ans=2.0*Pi*r; 79 for(int i=2;i<=top;i++) 80 ans+=Dis(st[i],st[i-1]); 81 printf("%.2f ",ans); 82 return 0; 83 }