想看更多的解题报告: 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;
}