luogu P3829 [SHOI2012]信用卡凸包
题面传送门
什么时候ZJOI能像SHOI那样啊qwq
显然一个凸包转了一圈,每个转弯的地方都是圆弧,所以直接把圆弧扔了求圆心凸包然后加上一个圆的周长即可。
然而这道题是真的坑。
首先是先读入竖直再水平,然后还有精度问题。
code:
#include<cstdio>
#include<cmath>
#include<algorithm>
#define eps 1e-5
#define I inline
#define db double
#define N 100039
using namespace std;
const db pi=acos(-1);
int n,sh;db ans,a,b,r,x,y,z,nx,ny;
struct yyy{db x,y;}f[N],st[N];
I db dis(yyy x,yyy y){return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));}
I bool cmp(yyy x,yyy y){return x.x==y.x?(x.y<y.y):(x.x<y.x);}
I db make(yyy x,yyy y,yyy a,yyy b){return (y.x-x.x)*(b.y-a.y)-(y.y-x.y)*(b.x-a.x);}
int main(){
freopen("1.in","r",stdin);
register int i;
scanf("%d%lf%lf%lf",&n,&b,&a,&r);a=a/2-r;b=b/2-r;
for(i=1;i<=n;i++){
scanf("%lf%lf%lf",&x,&y,&z);nx=cos(z);ny=sin(z);
a*=-1;f[i*4-3]=(yyy){a*nx-b*ny+x,b*nx+a*ny+y};
b*=-1;f[i*4-2]=(yyy){a*nx-b*ny+x,b*nx+a*ny+y};
a*=-1;f[i*4-1]=(yyy){a*nx-b*ny+x,b*nx+a*ny+y};
b*=-1;f[i*4]=(yyy){a*nx-b*ny+x,b*nx+a*ny+y};
}
sort(f+1,f+4*n+1,cmp);
for(sh=-1,i=1;i<=4*n;i++){
while(sh>=1&&make(st[sh-1],st[sh],st[sh-1],f[i])<eps) sh--;
st[++sh]=f[i];
}
for(i=1;i<=sh;i++) ans+=dis(st[i],st[i-1]);
for(sh=-1,i=4*n;i;i--){
while(sh>=1&&make(st[sh-1],st[sh],st[sh-1],f[i])<eps) sh--;
st[++sh]=f[i];
}
for(i=1;i<=sh;i++) ans+=dis(st[i],st[i-1]);
printf("%.2lf\n",ans+2*r*pi);
}

浙公网安备 33010602011771号