HDU 1392 Surround the Trees

来源:互联网 发布:淘宝封号能自动解封吗 编辑:程序博客网 时间:2024/06/07 00:59
Problem Description
There are a lot of trees in an area. A peasant wants to buy a rope to surround all these trees. So at first he must know the minimal required length of the rope. However, he does not know how to calculate it. Can you help him?
The diameter and length of the trees are omitted, which means a tree can be seen as a point. The thickness of the rope is also omitted which means a rope can be seen as a line.



There are no more than 100 trees.
 

Input
The input contains one or more data sets. At first line of each input data set is number of trees in this data set, it is followed by series of coordinates of the trees. Each coordinate is a positive integer pair, and each integer is less than 32767. Each pair is separated by blank.

Zero at line for number of trees terminates the input for your program.
 

Output
The minimal length of the rope. The precision should be 10^-2.
 

Sample Input
9 12 7 24 9 30 5 41 9 80 7 50 87 22 9 45 1 50 7 0
 

Sample Output
243.06
 

Source
Asia 1997, Shanghai (Mainland China) 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
第一次写凸包,感觉实在是太神奇了~

因为排序排反了WA了一次,其实输出一下就看出来了。
这个是最基本的Graham-Scan算法,时间复杂度是O(n*log(n))。
另外读入时要写成while(scanf("%d",&n)!=EOF && n),否则会超时。(好像只有ACM才会这样?很新奇呢~)
#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>using namespace std;struct node{double x,y;}tree[106],result[106];double ans;int n,top;double dis(node u,node v){return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y));}double multiply(node k1,node k2,node k3)  //叉积 QAQ {return ( (k2.x-k1.x)*(k3.y-k1.y)-(k2.y-k1.y)*(k3.x-k1.x) );}bool cmp(node u,node v){double m=multiply(tree[0],u,v);if(m<0) return 0;else if(m=0 && dis(u,tree[0])<dis(v,tree[0]))return 0;else return 1;}void tubao(){result[0].x=tree[0].x;result[0].y=tree[0].y;result[1].x=tree[1].x;result[1].y=tree[1].y;result[2].x=tree[2].x;result[2].y=tree[2].y;top=2;for(int i=3;i<=n;i++){while (multiply(result[top-1],result[top],tree[i])<=0)  //注意第一个不是result[0]    top--;result[++top].x=tree[i].x;result[top].y=tree[i].y;}}int main(){int k;double xx,yy;while(scanf("%d",&n)!=EOF && n){xx=yy=-1;for(int i=0;i<n;i++){scanf("%lf%lf",&tree[i].x,&tree[i].y);}if(n==1)  //要考虑n=1或2的特殊情况  {printf("0.00\n");continue;}if(n==2){printf("%.2lf\n",dis(tree[0],tree[1]));continue;}for(int i=0;i<n;i++){if(xx==-1 || yy>tree[i].y || (yy==tree[i].y && xx>tree[i].x))  xx=tree[i].x,yy=tree[i].y,k=i;}if(k!=0) swap(tree[0],tree[k]);tree[n].x=xx;tree[n].y=yy;  //后面计算会简单一些,一定要加,否则最后会少第一边  sort(tree+1,tree+n,cmp);tubao();ans=0.0;for(int i=0;i<top;i++) ans+=dis(result[i],result[i+1]);printf("%.2lf\n",ans);}return 0;}


2 0
原创粉丝点击