HDU1392Surround the Trees(凸包判断 + 求周长)
2016-03-18 14:53
387 查看
http://www.cnblogs.com/hmhard/archive/2013/02/05/2893035.html 这是判断三角区域那块写的不好。
判断凸包的方法:
1、将所有点按照y从小到大排序,x从小到大排序
2、现将前两个点放入栈中,然后判断下一个点在这两个点组成的线段的左边还是右边,左边的话,直接加入栈中, 如果在右边的话,就不行了,为了让这个点行,所以栈顶元素出栈,然后在判断栈中前两个组成的线段 跟 这个点个关系...其实这个关键就是不顾一切的让这个点进栈,即使把栈中的元素全部弹出来(当然不会,会留有一个)
3、弄完之后其实最大的那个点已经在栈中了,然后在反过来,从这个最大的开始像之前一样判断。
4、最后弄完,栈顶和栈底都是最小的那个元素。
---------------------------------------------------
三角区域判断:
借助向量,对于OA 和 OB ,如果 Xa Yb - XbYa > 0,OB在OA的右侧,如果小于0,OB在OA的左侧,如果相等共线
---------------------------------------------------------
HD1392
题意:N个点,然后输入N个点的坐标,问形成凸包的周长
View Code
判断凸包的方法:
1、将所有点按照y从小到大排序,x从小到大排序
2、现将前两个点放入栈中,然后判断下一个点在这两个点组成的线段的左边还是右边,左边的话,直接加入栈中, 如果在右边的话,就不行了,为了让这个点行,所以栈顶元素出栈,然后在判断栈中前两个组成的线段 跟 这个点个关系...其实这个关键就是不顾一切的让这个点进栈,即使把栈中的元素全部弹出来(当然不会,会留有一个)
3、弄完之后其实最大的那个点已经在栈中了,然后在反过来,从这个最大的开始像之前一样判断。
4、最后弄完,栈顶和栈底都是最小的那个元素。
---------------------------------------------------
三角区域判断:
借助向量,对于OA 和 OB ,如果 Xa Yb - XbYa > 0,OB在OA的右侧,如果小于0,OB在OA的左侧,如果相等共线
---------------------------------------------------------
HD1392
题意:N个点,然后输入N个点的坐标,问形成凸包的周长
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; struct Node { int x, y; }; Node node[110], ch[110]; int cmp(Node tempx, Node tempy) { if(tempx.y == tempy.y) return tempx.x < tempy.x; return tempx.y < tempy.y; } int xmult(Node p1, Node p2, Node p3) { return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y); } double dist(Node p1, Node p2) { return sqrt( (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) ); } int andrew(int n) { int len, top = 1; ch[0] = node[0]; ch[1] = node[1]; for(int i = 2; i < n; i++) { while(top && xmult(ch[top - 1], ch[top], node[i]) <= 0) // 保证top>0的情况下才能出栈,因为top等于0,出栈就空了 top--; ch[ ++top ] = node[i]; } len = top; ch[++top] = node[n - 2]; for(int i = n - 3; i >= 0; i--) { while(top != len && xmult(ch[top - 1], ch[top], node[i]) <= 0) // 这个也要保证当前栈最小是len,如果 > len可以出栈 top--; ch[ ++top ] = node[i]; } return top; } int main() { int n; while (scanf("%d", &n) != EOF && n) { for(int i = 0; i < n; i++) scanf("%d%d", &node[i].x, &node[i].y); sort(node, node + n, cmp); int top = andrew(n); double ans = 0; //for(int i = 0; i <= top; i++) // cout << ch[i].x << " " << ch[i].y << endl; for (int i = 1 ; i < top ; i ++) ans += dist(ch[i - 1] , ch[i]); if (top > 2) // 如果两个点以上还要计算一下栈底 和 次栈底的距离 ans += dist(ch[0], ch[top - 1]); printf("%.2lf\n" , ans); } return 0; }
View Code
相关文章推荐
- salesforce 零基础开发入门学习(五)异步进程介绍与数据批处理Batchable
- java(DOM、SAX、JDOM、DOM4J)xml方式详解与比较
- python的【爬虫】:使用urllib爬取wiki文章,使用beautifulSoup解析html
- 读取数据
- Android加载长图那些事
- GC基础
- 使用ant脚本生成war包
- WEB应用图片的格式,以及各自的特点和优化(一) by FungLeo
- easyui datagrid 数据汇总
- Druid创始人Eric Tschetter详解开源实时大数据分析系统Druid
- 面向对象的总结
- 利用python编写东北大学自动联网程序
- HDU 3188 Just A Triangle [Ad Hoc]
- GetPrivateProfileString和WritePrivateProfileString头文件引入的注意点
- java实现玩牌
- 华为2015年机试题(1)
- 理解MySQL——索引与优化
- object_setInstanceVariable is unavailable: not available in automatic reference counting mode
- 【堆栈应用二】迷宫算法,可直接动态运行
- (转)google Java编程风格中文版