http://hzwer.com/6330.html
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define N 100001 #define EPS 0.00000001 typedef double db; const db PI=acos(-1.0); struct Point{db x,y;}p[N<<2],bao[N<<2]; bool operator < (Point a,Point b){return fabs(a.x-b.x)>=EPS?a.x<b.x:a.y<b.y;} typedef Point Vector; Vector operator + (Vector a,Vector b){return (Vector){a.x+b.x,a.y+b.y};} Vector operator - (Vector a,Vector b){return (Vector){a.x-b.x,a.y-b.y};} Vector Rotate(Vector a,db rad) {return (Vector){a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad)};} db sqr(db x){return x*x;} db Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;} db dist(Point a,Point b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));} int n,m,en; db a,b,r,mx,my,jiao,ans; int main() { scanf("%d%lf%lf%lf",&n,&b,&a,&r); a-=(2.0*r); b-=(2.0*r); for(int i=1;i<=n;++i) { scanf("%lf%lf%lf",&mx,&my,&jiao); p[++m]=Rotate((Vector){a*0.5,b*0.5},jiao)+(Point){mx,my}; p[++m]=Rotate((Vector){(-a)*0.5,b*0.5},jiao)+(Point){mx,my}; p[++m]=Rotate((Vector){a*0.5,(-b)*0.5},jiao)+(Point){mx,my}; p[++m]=Rotate((Vector){(-a)*0.5,(-b)*0.5},jiao)+(Point){mx,my}; } sort(p+1,p+1+m); for(int i=1;i<=m;++i) { while(en>1&&Cross(bao[en]-bao[en-1],p[i]-bao[en])<=0.0) --en; bao[++en]=p[i]; } int t=en; for(int i=m-1;i;--i) { while(en>t&&Cross(bao[en]-bao[en-1],p[i]-bao[en])<=0.0) --en; bao[++en]=p[i]; } for(int i=2;i<=en;++i) ans+=dist(bao[i-1],bao[i]); printf("%.2f ",ans+dist(bao[en],bao[1])+PI*r*2.0); return 0; }