把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

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);
} 
posted @ 2021-04-04 18:57  275307894a  阅读(37)  评论(0)    收藏  举报
浏览器标题切换
浏览器标题切换end