ZOJ 1465 Wall (POJ 1113)(凸包)

裸凸包,不解释,也没有啥要注意的,直接硬上就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;
}


你可能感兴趣的:(struct,ini)