想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:给出N个点,问要建一座围墙把这N个点都围起来,并且这做围墙和点的距离不能小于L,问怎么使围墙最短
解题思路:虽然一下就想到了凸包,然后自己写GS算法,结果调了一天,最后发现是定义PI的宏写错了,无限汗颜中,A了之后我很天真的想用两个向量的cos角度去排序,但是怎么调试都是WA,所以还是老实的用叉积排序吧
/* 200K 32MS */ #include <stdio.h> #include <stdlib.h> #include <math.h> #define INF 1<<30 #define MAXV 1010 #define PI 3.141592653 struct Point{ double x,y; }point[MAXV],tmp; int n,l; double distance(double x1,double y1,double x2,double y2){ double dis=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); return sqrt(dis); } int cacl(struct Point a,struct Point b,struct Point h){ //求cos<ha,x>于cos<hb,x>的大小 double ta=1.0*(a.x-h.x)/distance(a.x,a.y,h.x,h.y); double tb=1.0*(b.x-h.x)/distance(b.x,b.y,h.x,h.y); if(ta > tb) return 1; if(ta==tb) return 0; return -1; } double chaji(struct Point a1,struct Point b1,struct Point a2,struct Point b2){ //求<a1,b1>向量和<a2,b2>向量的叉积 double x1=b1.x-a1.x; double y1=b1.y-a1.y; double x2=b2.x-a2.x; double y2=b2.y-a2.y; return x1*y2-x2*y1; } int cmp(const void *p1,const void *p2){ //排序的比较函数 struct Point *a=(struct Point *)p1; struct Point *b=(struct Point *)p2; double flag=chaji(point[0],*a,point[0],*b); //int flag=cacl(*a,*b,point[0]); 用cos排序错了,- - ! if(flag>0) return -1; //如果角度是a>b的就直接返回 else if(!flag && distance((a->x),(a->y),point[0].x,point[0].y)<distance((b->x),(b->y),point[0].x,point[0].y)) //如果角度a==b的那么取距离小的那一点在前面 return -1; return 1; } int findminp(){ //找到最左下点 int i,v; double ymin=INF,xmin=INF; for(i=0;i<n;i++) if(point[i].y<ymin) v=i,ymin=point[i].y; for(i=0;i<n;i++) if(point[i].y==ymin && point[i].x<xmin) v=i,xmin=point[i].x; return v; } double graham(){ int d[MAXV],dtop=0; //模拟栈 int i; double sum; d[dtop++]=0; d[dtop++]=1; //前两点入栈 for(i=2;i<n;i++){ while(chaji(point[d[dtop-2]],point[d[dtop-1]],point[d[dtop-1]],point[i])<0) dtop--; d[dtop++]=i; } sum=0; for(i=1;i<dtop;i++){ sum+=distance(point[d[i]].x,point[d[i]].y,point[d[i-1]].x,point[d[i-1]].y); } sum+=distance(point[d[i-1]].x,point[d[i-1]].y,point[d[0]].x,point[d[0]].y); return sum; } int main(){ int i,h; double ans; while(~scanf("%d%d",&n,&l)){ for(i=0;i<n;i++){ scanf("%lf%lf",&point[i].x,&point[i].y); } h=findminp(); tmp=point[0]; point[0]=point[h]; point[h]=tmp; qsort(point+1,n-1,sizeof(point[0]),cmp); ans=graham()+(2.0*PI*l); printf("%.0lf\n",ans); } return 0; }