计算几何相关知识及基本算法 (C语言版) http://blog.csdn.net/cschf/article/details/2489462
#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];
double r;
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;
}
double f(int n){
int i,top;
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;
return s;
}
int main()
{ double s;
scanf("%d%lf",&n,&r);
s=f(n);
printf("%.0lf\n",s);
system("pause");
return 0;
}