题目链接:http://poj.org/problem?id=1113
#include<iostream> #include<cstdio> #include<cmath> #include<stack> using namespace std; #define pi 3.14159265358 typedef struct point { int x,y; }rr; point a[1005],*p; int b[1005]; int n,l; int Sort(point p1,point p2,point p3,point p4) { int t=(p2.x-p1.x)*(p4.y-p3.y)-(p4.x-p3.x)*(p2.y-p1.y); return t; } int distance(point p1,point p2,point p3,point p4) { return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)>(p3.x-p4.x)*(p3.x-p4.x)+(p3.y-p4.y)*(p3.y-p4.y)?1:-1; } int cmp(const void *a,const void *b) { point *c=(point *)a; point *d=(point *)b; int temp=Sort(*p,*c,*p,*d); if(temp<0) return 1; else if(temp==0) return distance(*p,*c,*p,*d); else return -1; } void foud()//将点集合的所有的外边的点找出来 { int i,pc=2; b[1]=0; b[2]=1; b[0]=2;//记录的是总的个数的 for(i=2; ;) { i=i%n;///需要将0的也进行一下再结合 if(i==1) break; if(b[0]==1) { b[++pc]=i++; b[0]++; continue; } if(Sort(a[b[pc-1]],a[b[pc]],a[b[pc]],a[i])<=0)//删除pc所在的那个店的 { pc--; b[0]--; } else { b[++pc]=i++;//最后的栈的后面多了一个0是为了下面进行的操作的 b[0]++; } } n=pc-1;//1到pc的结果的 b[0]=b[pc-1];//为了循环的 // for(i=0; i<=n+1; i++) // printf("%d\n",b[i]); } double dis(point p1,point p2) { double s=(double)((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); s=sqrt(s); return s; } double degree(point p1,point p2,point p3,point p4) { double s=(double)((p2.x-p1.x)*(p4.x-p3.x)+(p2.y-p1.y)*(p4.y-p3.y)); double t=dis(p1,p2)*dis(p3,p4); return acos(s/t);//算出来的是角度 } void len() { double Max=0; int i; for(i=1; i<=n; i++) Max+=sqrt((double)((a[b[i]].x-a[b[i+1]].x)*(a[b[i]].x-a[b[i+1]].x)+(a[b[i]].y-a[b[i+1]].y)*(a[b[i]].y-a[b[i+1]].y)));//求一部分的边长的 for(i=1; i<=n; i++) { double m=degree(a[b[i]],a[b[i-1]],a[b[i]],a[b[i+1]]); m=pi-m;//对角的 Max+=l*m; } printf("%d\n",(int)(Max+0.5)); } int main() { int i,j,x,y; while(scanf("%d%d",&n,&l)!=EOF) { x=INT_MAX; y=INT_MAX; for(i=0; i<n; i++) { scanf("%d%d",&a[i].x,&a[i].y); if(a[i].y<y) { y=a[i].y;j=i;x=a[i].x; } else if(a[i].y==y && a[i].x<x) { y=a[i].y;j=i;x=a[i].x; } } a[j].x=a[0].x;a[j].y=a[0].y; a[0].x=x;a[0].y=y; p=&a[0]; qsort(&a[1],n-1,sizeof(point),cmp); // for(i=0; i<n; i++) // printf("%d %d %d\n",i,a[i].x,a[i].y); foud(); len();//计算需要的篱笆的长度 } return 0; }