Surround the Trees

题意:

Surround the Trees

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 209 Accepted Submission(s): 104

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)

Recommend

Ignatius.L

题目分析:

求凸包的周长。这道题和拿到Wall的题目是差不多。需要注意一下的是,这道题中的结点的个数可能<=2,这个需要单独处理一下。

代码如下:

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;const double epsi = 1e-8;const double pi = acos(-1.0);const int maxn = 101;struct PPoint{//结构体尽量不要定义成Point这种,容易和C/C++本身中的变量同名double x;double y;PPoint(double _x = 0,double _y = 0):x(_x),y(_y){}PPoint operator – (const PPoint& op2) const{return PPoint(x – op2.x,y – op2.y);}double operator^(const PPoint &op2)const{return x*op2.y – y*op2.x;}};inline int sign(const double &x){if(x > epsi){return 1;}if(x < -epsi){return -1;}return 0;}inline double sqr(const double &x){return x*x;}inline double mul(const PPoint& p0,const PPoint& p1,const PPoint& p2){return (p1 – p0)^(p2 – p0);}inline double dis2(const PPoint &p0,const PPoint &p1){return sqr(p0.x – p1.x) + sqr(p0.y – p1.y);}inline double dis(const PPoint& p0,const PPoint& p1){return sqrt(dis2(p0,p1));}int n;PPoint p[maxn];PPoint convex_hull_p0;inline bool convex_hull_cmp(const PPoint& a,const PPoint& b){return sign(mul(convex_hull_p0,a,b)>0)|| (sign(mul(convex_hull_p0,a,b)) == 0 && dis2(convex_hull_p0,a) < dis2(convex_hull_p0,b));}int convex_hull(PPoint* a,int n,PPoint* b){int i;for(i = 1 ; i < n ; ++i){if(sign(a[i].x – a[0].x) < 0 || (sign(a[i].x – a[0].x) == 0 && sign(a[i].y – a[0].y) < 0)){swap(a[i],a[0]);}}convex_hull_p0 = a[0];//这两行代码不要顺序调换了..否则会WAsort(a,a+n,convex_hull_cmp);b[0] = a[0];b[1] = a[1];int newn = 2;for(i = 2 ; i < n ; ++i){while(newn > 1 && sign(mul(b[newn-1],b[newn-2],a[i])) >= 0){newn–;}b[newn++] = a[i];}return newn;}int main(){while(scanf("%d",&n)!=EOF,n){int i;for(i = 0 ; i < n ; ++i){scanf("%lf %lf",&p[i].x,&p[i].y);}/** * 一定要注意的是,这道题中可能存在结点数 <= 2的情况. * 而graham计算凸包的算法只适用于结点数>=3的情况. * 所以需要对节点数<=2的情况做一下处理… */if(n < 2){//如果节点数<2printf("0.00\n");//则直接输出0.00continue;//进行下一次循环}if(n == 2){//如果结点数 == 2printf("%.2lf\n",dis(p[0],p[1]));//则直接计算p[0]和p[1]的距离即可..continue;//进行下一次循环}n = convex_hull(p,n,p);p[n] = p[0];//首尾相接.将最后一个点指向起点double ans = 0;for(i = 0 ; i < n ; ++i){//计算凸包的周长ans += dis(p[i],p[i+1]);}printf("%.2lf\n",ans);}return 0;}

,往往教导我们大家要好好学习天天向上,要永不言弃坚持到底百折不挠宁死不屈,

Surround the Trees

相关文章:

你感兴趣的文章:

标签云: