计算几何 graham 最大凸包
来源:互联网 发布:nothing软件怎么样 编辑:程序博客网 时间:2024/06/06 09:17
http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11326&courseid=117
对于ACMer来说,这么严格复杂的定义可能是没有必要的。我们只要知道平面有限点集的凸包是一个凸多边形就行了。
现在的问题是给定一个平面点集,求出其“严格凸多边形”的凸包。“严格”的意思是凸多边形的边上没有任意三点共线。Input 输入有多个案例。每个案例的第一行是一个整数n,n≤100。随后n行,每一行有2个整数,表示点的x、y坐标,0≤x、y≤2147483647。一个单独的0表示输入结束。没有任何点的坐标是完全一样的。Output 对每一个案例,首先输出一行为其端点的个数,然后按逆时针输出其凸包的顶点的坐标。输出起点是所有顶点的最下最左点(首先是最下,如果有多个点同样处于最下,则取最靠左的)。每个顶点输出一行,中间用空格隔开。Sample Input
30 0100 100100 00Sample Output
30 0100 0100 100
//严格凸包#include <cstdio>#include <cmath>#include <algorithm>using namespace std;typedef long long llt;#define SIZE 101struct point_t{llt x,y;}P[101];//叉积,OA×OBllt cross(point_t const&O,point_t const&A,point_t const&B){ llt xoa = A.x - O.x;llt yoa = A.y - O.y;llt xob = B.x - O.x;llt yob = B.y - O.y;return xoa * yob - xob * yoa;}//A如果比B更靠下更靠左返回真bool isLowLeft(point_t const&A,point_t const&B){return A.y < B.y || ( A.y == B.y && A.x < B.x );}//按照对于pO的极角排序,极角相等的距离远的排在前面,因为后面要做一个uniquepoint_t* pO;bool comp4Graham(point_t const&A,point_t const&B){ llt t = cross(*pO,A,B);if ( t ) return t > 0LL;llt a1 = A.x > pO->x ? A.x - pO->x : pO->x - A.x;llt a2 = B.x > pO->x ? B.x - pO->x : pO->x - B.x; if ( a1 != a2 ) return a1 > a2;a1 = A.y > pO->y ? A.y - pO->y : pO->y - A.y;a2 = B.y > pO->y ? B.y - pO->y : pO->y - B.y;return a1 > a2;}//相对于pO是否极角相等bool isEqPolar(point_t const&A,point_t const&B){ return 0LL == cross(*pO,A,B);}//Graham求凸包,结果当中没有共线点,起点总是最下最左点int Graham(point_t P[],int n){ if ( 1 == n ) return 1;//寻找最下最左点point_t *p = min_element(P,P+n,isLowLeft);//交换swap(*p,P[0]);if ( 2 == n ) return 2;//按极角排序,极角相等,距离近的排在前面pO = P;sort(P+1,P+n,comp4Graham);//将相对于pO的共线点均剔除,只保留最后一个p = unique(P+1,P+n,isEqPolar);n = p - P;//真正的Graham循环int top = 2;for(int i=2;i<n;++i){while( top > 1 && cross(P[top-2],P[top-1],P[i]) <= 0LL )--top;P[top++] = P[i];}return top;}int main(){int n;while( scanf("%d",&n) && n ){ for(int i=0;i<n;++i)scanf("%I64d%I64d",&P[i].x,&P[i].y);n = Graham(P,n);printf("%d\n",n);for(int i=0;i<n;++i)printf("%I64d %I64d\n",P[i].x,P[i].y);}return 0;
http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11327&courseid=117
对于ACMer来说,这么严格复杂的定义可能是没有必要的。我们只要知道平面有限点集的凸包是一个凸多边形就行了。
现在的问题是给定一个平面点集,求出其“不严格”凸多边形的凸包。“不严格”的意思是指将凸包边界上所有的点都看作是多边形的端点。
Input 输入有多个案例。每个案例的第一行是一个整数n,n≤100。随后n行,每一行有2个整数,表示点的x、y坐标,0≤x、y≤2147483647。一个单独的0表示输入结束。
Output 对每一个案例,首先输出一行为多边形端点的个数,然后按逆时针输出其凸包的顶点的坐标。输出起点是所有顶点的最下最左点(首先是最下,如果有多个点同样处于最下,则取最靠左的)。每个顶点输出一行,中间用空格隔开。
Sample Input
40 0100 100100 050 00Sample Output
40 050 0100 0100 100
严格凸包是在极角排序的时候提前做了处理,所以我们只要把处理取反即可, 代码上只要把极角相等的时候改成近的放前面,去掉unique函数。
typedef long long llt;struct point_t{llt x,y;}P[101];llt cross(point_t const&O,point_t const&A,point_t const&B){ llt xoa = A.x - O.x;llt yoa = A.y - O.y;llt xob = B.x - O.x;llt yob = B.y - O.y;return xoa * yob - xob * yoa;}bool isLowLeft(point_t const&A,point_t const&B){return A.y < B.y || ( A.y == B.y && A.x < B.x );}point_t* pO;bool comp4Graham(point_t const&A,point_t const&B){ llt t = cross(*pO,A,B);if ( t ) return t > 0LL;llt a1 = A.x > pO->x ? A.x - pO->x : pO->x - A.x;llt a2 = B.x > pO->x ? B.x - pO->x : pO->x - B.x; if ( a1 != a2 ) return a1 < a2; //把这个变成近的放前面a1 = A.y > pO->y ? A.y - pO->y : pO->y - A.y;a2 = B.y > pO->y ? B.y - pO->y : pO->y - B.y;return a1 > a2;}bool isEqPolar(point_t const&A,point_t const&B){ return 0LL == cross(*pO,A,B);}int Graham(int n){ if ( 1 == n ) return 1;point_t *p = min_element(P,P+n,isLowLeft);swap(*p,P[0]);if ( 2 == n ) return 2;pO = P;sort(P+1,P+n,comp4Graham); //去掉这个//p = unique(P+1,P+n,isEqPolar);//n = p - P;int top = 2;for(int i=2;i<n;++i){while( top > 1 && cross(P[top-2],P[top-1],P[i]) < 0LL )--top;P[top++] = P[i];}return top;}int main(){int n;while( scanf("%d",&n) && n ){ for(int i=0;i<n;++i)scanf("%I64d%I64d",&P[i].x,&P[i].y);n = Graham(n);printf("%d\n",n);for(int i=0;i<n;++i)printf("%I64d %I64d\n",P[i].x,P[i].y);}return 0;}
1 0
- 计算几何 graham 最大凸包
- 计算几何之凸包----Graham扫描法
- poj 1113 Wall 计算几何 凸包 Graham扫描
- 计算几何 : 凸包学习笔记 --- Graham 扫描法
- [caioj]1214:【计算几何】凸包 graham scan求凸包
- [caioj]1214:【计算几何】凸包 graham scan求凸包
- 最小凸包算法(Convex Hull)(1)-Graham扫描法 -计算几何-算法导论
- 【计算几何初步-凸包-Graham扫描法-极角序】【HDU1348】 WALL
- 计算几何之二维凸包:卷包裹算法、Graham Scan Algorithm、旋转卡壳算法
- Graham算法(计算凸包周长)
- 【BZOJ1069】【SCOI2007】最大土地面积 计算几何 凸包
- 计算几何-凸包
- [计算几何]凸包算法
- 计算几何之凸包
- 计算几何-凸包问题
- 计算几何 --- 凸包 模板
- 计算几何凸包详解
- 凸包 graham 算法
- 23种设计模式C++实例之观察者模式
- CodeForces 589B -- B. Layer Cake(多重集合+技巧枚举)
- 2016多校训练Contest7: 1004 Distance hdu5812
- qml 实现图片旋转, 且鼠标可以拖动图片,鼠标点击在两幅图片间切换
- bjfu1004 Sudoku
- 计算几何 graham 最大凸包
- ORA-01795:列表中的最大表达式数为1000
- 排序算法
- 测试
- 盘点最受欢迎的十个开源大数据技术
- 如何提高自己的口才-02
- 简明教程 装Windows系统
- 项目unlix电信计时收费2
- 网站架构演变