裸凸包,不解释,也没有啥要注意的,直接硬上就OK
不过我发现 sort 的确比 qsort 快一点,XH用一个 qsort 做点集的角排序,我用的是 sort ,时间比 XH 的短一些……
而且 sort 写着挺方便的说……
代码:
#include<iostream> #include<stdio.h> #include<math.h> #include<stdlib.h> #include<algorithm> #define N 1000 #define esp 1e-8 #define pi acos(-1.0) using namespace std; int n,stk[N]; struct point { double x,y; }; point p[N],kp; //kp为基准点 double dis2(point a,point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } double xmult(point a,point b,point kp) //a,b点分别于基准点 kp 的连线向量的叉乘 //返回值为正时,a点在b点的顺时针方向 //返回值为负时,a点在b点的逆时针方向 { return (a.x-kp.x)*(b.y-kp.y)-(b.x-kp.x)*(a.y-kp.y); } int cmp_point(const void *a,const void *b) //点排序,找最左下的点 { struct point *aa=(struct point *)a; struct point *bb=(struct point *)b; if(fabs(aa->x - bb->x)>esp) //即aa->x != bb->x return aa->x > bb->x ? 1:-1; else return aa->y > bb->y ? 1:-1; } bool cmp_angle(point a,point b) { double xx=xmult(a,b,kp); if(fabs(xx)<esp) return dis2(a,kp) < dis2(b,kp)?1:0; else return xx>0?1:0; } int main() { int i,top,t; double r; scanf("%d",&t); while(t--) { scanf("%d%lf",&n,&r); for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); qsort(p,n,sizeof(p[0]),cmp_point);//快排找最右下的点为基准点 kp=p[0]; sort(p+1,p+n,cmp_angle); for(top=0;top<2;stk[top]=top++); //前两个点入栈 for(i=2;i<n;i++) { while( xmult(p[ stk[top-1] ],p[i],p[ stk[top-2] ]) < esp && top > 1)top--; //如果叉积为0,说明 i 点在p[top-2],p[top-1]上,取最远一点,较近点出栈 stk[top++]=i; } double s=sqrt( dis2(p[0],p[ stk[top-1] ]) ); for(i=0;i<top-1;i++) s+=sqrt( dis2(p[stk[i]],p[stk[i+1]]) ); s+=2*pi*r; printf("%.0lf\n",s); if(t>0)puts(""); } return 0; }