HDU 1392 Surround the Trees(凸包模板)

来源:互联网 发布:手机阅读软件mobi 编辑:程序博客网 时间:2024/05/17 09:42

Surround the Trees

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10464    Accepted Submission(s): 4062


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


分析:给n个点,求出把所有点包围进去的所有边的和。

计算凸包的步骤:

平面上三个点:p1(x1,y1),p2(x2,y2),p3(x3,y3)

s(p1,p2,p3)=(x1-x3)*(y2-y3)-(x2-x3)*(y1-y3)

如果s>0 则说明 这连接这3个点时是按照逆时针的顺序,如果是s<0则说明连接这3个点是按照顺时针的顺序

1、排序:先按y从小到大排序,y相等时,按x从下到大排序。

bool cmp(node a,node b){if(a.y==b.y)return a.x<b.x;return a.y<b.y;}

2、判断n是否大于3(小于3围不成凸多边形),然后对初始三个点赋值。

if(n==1)return 0;if(n==2)return dist(ans[0],ans[1]);res[0]=ans[0];res[1]=ans[1];res[2]=ans[2];

3、逆时针方向计算,先从右半边开始算,从第2个点开始,如果新加入的点,与之前确定点的向量的叉乘小于0的话,说明该点在之前的点的右面,不满足凸包,所以删除之前确定的点,top--

    for(i=2;i<n;i++){        while(top && mult(ans[i],res[top],res[top-1])) //左转退栈,上凸包        top--;        res[++top]=ans[i];    }

4、再从左半边开始算,从第2个点开始,如果新加入的点,与之前确定点的向量的叉乘小于0的话,说明该点在之前的点的左,不满足凸包,所以删除之前确定的点,top--


    for(i=n-3;i>=0;i--){        while(top!=len && mult(pnt[i],res[top],res[top-1]))//下凸包。            top--;        res[++top]=pnt[i];    }

5、向量叉乘函数

bool mult(node a,node b,node t){return (a.x-t.x)*(b.y-t.y)>=(b.x-t.x)*(a.y-t.y);}

AC代码如下:

#include <stdio.h>#include <algorithm>#include <math.h>using namespace std;struct node{int x,y;}ans[105];bool cmp(node a,node b){if(a.y==b.y)return a.x<b.x;return a.y<b.y;}double dist(node a,node b){return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}bool mult(node a,node b,node t){return (a.x-t.x)*(b.y-t.y)>=(b.x-t.x)*(a.y-t.y);}double grahum(int n){int len,i,j,k,top=1;node res[105];sort(ans,ans+n,cmp);if(n==1)return 0;if(n==2)return dist(ans[0],ans[1]);res[0]=ans[0];res[1]=ans[1];res[2]=ans[2];    for(i=2;i<n;i++){        while(top && mult(ans[i],res[top],res[top-1])) //左转退栈,上凸包        top--;        res[++top]=ans[i];    }len = top;res[++top]=ans[n-2];    for(i=n-3;i>=0;i--){        while(top!=len && mult(ans[i],res[top],res[top-1]))//下凸包。            top--;        res[++top]=ans[i];    }double result=.0;for(i=1;i<=top;i++){result+=dist(res[i],res[(i+1)>top?1:(i+1)]);}return result;}int main(){int n;int i,j;while(scanf("%d",&n),n){for(i=0;i<n;i++)scanf("%d %d",&ans[i].x,&ans[i].y);printf("%.2lf\n",grahum(n));}return 0;}



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 8个月的狗狗怕人不敢出门怎么办 狗太怕人了怎么办都不敢出门 媳妇和婆婆晚上都不想带孩子怎么办 婆婆和媳妇带孩子观念不一样怎么办 婆婆给媳妇买了不喜欢的家具怎么办 断奶后宝宝对奶粉很抗拒怎么办 两岁宝宝断奶不喝奶粉怎么办 宝宝两岁了断奶后奶粉不吃怎么办 宝宝断奶两天了不愿意吃奶粉怎么办 一岁四个月宝宝断奶不喝奶粉怎么办 四个月宝宝断奶不喝奶粉怎么办 四个月宝宝断奶后不吃奶粉怎么办 2岁的宝宝不开口说话怎么办 一周岁宝宝断奶不喝奶粉怎么办 八个月宝宝断奶不喝奶粉怎么办 婆家人总是用心机对待娘家人怎么办 婆婆老是背后说我娘家人坏话怎么办 婆家姐带孩子住娘家不走怎么办? 老是想在娘家不想回婆家怎么办 娘家和婆家同时向我借钱怎么办 土地确权后娘家婆家都没有怎么办 结了婚婆家向娘家借钱怎么办? 婆婆的娘家人从我家住怎么办 八个月宝宝断奶后不吃奶粉怎么办 吃母乳的宝宝不吸奶嘴怎么办 宝宝吸了奶嘴不吸母乳怎么办 婴儿吃了奶嘴不吸母乳怎么办 十一个月宝宝断奶不喝奶粉怎么办 孩子三门成绩全不及格家长该怎么办 宝宝快十个月了还不会爬怎么办 小孩写字老把手向里扭曲怎么办 孩子该上四年级了数学差的很怎么办 孩子上三年级了数学成绩好差怎么办 三年级数学老考70-80分怎么办 叛逆期的孩子用死来威胁家长怎么办 叛逆期的孩子抽烟喝酒家长该怎么办 大学遇到不好的老师加课怎么办 两岁的宝宝脾气古怪不听话怎么办 16个月宝宝不听话脾气大怎么办 如果你很害怕去面对一件事怎么办 孩子上幼儿园哭老师不理孩子怎么办