HDU 1392 凸包子
2016-03-08 18:43
399 查看
Surround the Trees
[align=left][b]Problem Description[/b][/align]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.
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/9426b66e356d9461caf704dc6d111b17.gif)
There are no more than 100 trees.
[align=left][b]Input[/b][/align]
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.
[align=left][b]Output[/b][/align]
The minimal length of the rope. The precision should be 10^-2.
[align=left][b]Sample Input[/b][/align]
9
12 7
24 9
30 5
41 9
80 7
50 87
22 9
45 1
50 7
0
[align=left][b]Sample Output[/b][/align]
243.06
[b]题意:[/b]
简单的凸包模板题目
[b]题解:[/b]
这里介绍一种求凸包的算法:Graham。(相对于其它人的解释可能会有一些出入,但大体都属于这个算法的思想,同样可以解决凸包问题)
相对于包裹法的n*m时间,Graham算法在时间上有很大的提升,只要n*log(n)时间就够了。它的基本思想如下:
1、首先,把所有的点按照y最小优先,其次x小的优先排序
2、维护一个栈,用向量的叉积来判断新插入的点跟栈顶的点哪个在外围,如果栈顶的点在当前插入的点的左边,那么把栈顶的这个元素弹出,弹出之后不能继续插入下一个点,要继续判断当前插入点跟弹出之后的栈顶的点的位置关系,当当前插入的点在栈顶的那个点的左边时,则可以将要插入的点压到栈中,进入下一个点。
http://blog.csdn.net/bone_ace/article/details/46239187
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5+10, M = 30005, mod = 1e9 + 7, inf = 0x3f3f3f3f; typedef long long ll; struct point{ double x,y; point (double x = 0, double y = 0):x(x),y(y) {} friend point operator + (point a,point b) { return point(a.x+b.x,a.y+b.y); } friend point operator - (point a,point b) { return point(a.x-b.x,a.y-b.y); } }p ,res ; double dis(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double dot(point a,point b) { return a.x*b.y-b.x*a.y; } int cmp(point a,point b) { if(a.y==b.y) return a.x<b.x; else return a.y<b.y; } int Graham(point* p,int n,point* res) { sort(p+1,p+n+1,cmp); res[1] = p[1]; res[2] = p[2]; int top = 2,len; for(int i=3;i<=n;i++) { while(top>=2 && dot(p[i] - res[top-1],res[top] - res[top-1])>=0) top--; res[++top] = p[i]; } len = top; for(int i=n;i>=1;i--) { while(top!=len&&dot(p[i]-res[top-1],res[top]-res[top-1])>=0) top--; res[++top] = p[i]; } return top; } int main() { int n; while(scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); if(n==1) { printf("0.00\n");continue; } if(n==2) { printf("%.2f\n",dis(p[1],p )); continue; } int m=Graham(p,n,res); double tot=0; for(int i=2;i<=m;i++) tot+=dis(res[i-1],res[i]); printf("%.2f\n",tot); } }
相关文章推荐
- 使用mount挂载虚拟机所在的img文件
- css伪类写三角
- Android源代码目录组成介绍-android学习之旅(97)
- Android源代码目录组成介绍-android学习之旅(97)
- Android源代码目录组成介绍-android学习之旅(97)
- 教你使用rpm、yum、编译等方式安装软件
- 《哆啦A梦》周末票房夺冠,有望破自身纪录
- 批梯度下降法和随机梯度下降法(SGD)
- Android源代码目录组成介绍-android学习之旅(97)
- getElementById,getElementsByName,getElementsByTagName的区别
- linux创建vg、lv
- Codeforces--630N--Forecast(方程求解)
- ubuntu 14.04 安装phpMyAdmin + lighttpd
- MongoDB学习-入门
- Handler、Looper、MessageQueen、Message的关系及个人理解
- Codeforces--630N--Forecast(方程求解)
- 泛型继承接口Demo
- 坐标下降法
- 144 mysql 索引
- Javascript 操作 json 会遇到什么坑?