计算几何 二维凸包问题 Andrew算法
凸包:把给定点包围在内部的、面积最小的凸多边形。
Andrew算法是Graham算法的变种,速度更快稳定性也更好。
首先把全部点排序。依照第一keywordx第二keywordy从小到大排序,删除反复点后得到点序列P1...Pn。
1)把P1,P2放入凸包中,凸包中的点使用栈存储
2)从p3開始,当下一个点在凸包当前前进方向(即直线p1p2)左边的时候继续;
3)否则依次删除近期增加凸包的点,直到新点在左边。
如图,新点P18在当前前进方向P10P15的右边(使用叉积推断),因此须要从凸包上删除点P15和P10。让P8的下一个点为P18。反复该过程直到碰到最右边的Pn,求出下凸包即凸包的下轮廓。然后从Pn反过来反复该步骤求出上凸包,合并起来后就是完整的凸包。
该算法扫描为O(n)复杂度,排序O(nlogn)。
C++ code(刘汝佳《算法竞赛入门经典-训练指南》模板)
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- #include <cmath>
- using namespace std;
- const double eps = 1e-8,Pi=3.14159265;
- int n;
- inline int dcmp(double x)//三态函数
- {
- if(fabs(x) < eps) return 0;
- else return x>0 ?
- 1 : -1;
- }
- #define Vector Point
- struct Point
- {
- double x,y;
- inline Point(double x=0,double y=0):x(x),y(y) {}
- }p[10000+5],ch[10000+5];
- bool myCmp(Point A, Point B)
- {
- if(A.x != B.x) return A.x < B.x;
- else return A.y < B.y;
- }
- Vector operator + (Vector A, Vector B) {return Vector(A.x + B.x, A.y + B.y);}
- Vector operator - (Vector A, Vector B) {return Vector(A.x - B.x, A.y - B.y);}
- bool operator == (const Vector& A, const Vector& B) {return dcmp(A.x-B.x)==0 && dcmp(A.y-B.y)==0;}
- inline double Cross(Vector A, Vector B)//叉积
- {
- return A.x * B.y - A.y * B.x;
- }
- int ConvexHull()
- {
- sort(p,p+n,myCmp);
- int m = 0;
- for(int i = 0; i <n; i++)
- {
- while(m > 1 && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;
- ch[m++] = p[i];
- }
- int k = m;
- for(int i = n-2; i >= 0; i--)
- {
- while(m > k && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;
- ch[m++] = p[i];
- }
- if(n > 1) m--;
- return m;
- }
- double Dis(Point A, Point B)
- {
- return sqrt((A.x - B.x)*(A.x - B.x) + (A.y - B.y)*(A.y - B.y));
- }
- int main()
- {
- int m;
- cin>>n;
- for(int i = 0; i < n; i++)
- {
- int a,b;
- cin>>a>>b;
- p[i] = Point(a,b);
- }
- m = ConvexHull();
- //计算凸包周长
- double ans=0.0;
- for(int i = 0; i < m-1; i++)
- ans += Dis(ch[i],ch[i+1]);
- ans += Dis(ch[m-1],ch[0]);
- printf("%.1f",ans);
- }
例题:
wikioi1298(click me)
求解二维凸包并计算周长
wikioi3201(click me)
求解二维凸包并计算周长
本题翻译:http://blog.csdn.net/lytning/article/details/24046075
求解二维凸包并增加一个圆的周长
计算几何 二维凸包问题 Andrew算法的更多相关文章
- 二维凸包 Graham扫描算法
题目链接: http://poj.org/problem?id=1113 求下列点的凸包 求得凸包如下: Graham扫描算法: 找出最左下的点,设为一号点,将其它点对一号点连线,按照与x轴的夹角大小 ...
- Andrew算法求二维凸包-学习笔记
凸包的概念 首先,引入凸包的概念: (有点窄的时候...图片右边可能会被吞,拉开图片看就可以了) 大概长这个样子: 那么,给定一些散点,如何快速地求出凸包呢(用在凸包上的点来表示凸包) Andrew算 ...
- 【计算几何】二维凸包——Graham's Scan法
凸包 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内.右图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包. 一组平面上的点, ...
- Luogu P2742 模板-二维凸包
Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...
- UVA 10652 Board Wrapping(二维凸包)
传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组 ...
- 使用Graham扫描法求二维凸包的一个程序
#include <iostream> #include <cstring> #include <cstdlib> #include <cmath> # ...
- luogu P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows
题解: 二维凸包裸题 按照x坐标为第一关键字,y坐标为第二关键字排序 然后相邻判断叉积用单调队列搞过去 正反都做一次就好了 代码: #include <bits/stdc++.h> usi ...
- 【洛谷 P2742】【模板】二维凸包
题目链接 二维凸包板子..有时间会补总结的. #include <cstdio> #include <cmath> #include <algorithm> usi ...
- poj 2079 Triangle (二维凸包旋转卡壳)
Triangle Time Limit: 3000MS Memory Limit: 30000KB 64bit IO Format: %I64d & %I64u Submit Stat ...
随机推荐
- ashx 文件的使用
它就类似.aspx文件,用于处理传入到服务器的HTTP请求,但它不会像.aspx文件那样要返回处理结果和大量HTML,它可以返回简单的字符串.图片等. 百度百科定义链接:http://baike.ba ...
- IOS开发 键盘添加工具条 退出 上一项 下一项 简单实现
首先设置每个 UITextField 的 inputAccessoryView 为UIToolBar : 将所有的 textField 放入一个数组: 设置 UITextField UITextFie ...
- JS——select标签
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 4th 循环结构概述和for语句的格式及其使用
04.01_Java语言基础(循环结构概述和for语句的格式及其使用) A:循环结构的分类 for,while,do...while B:循环结构for语句的格式: for(初始化表达式;条件表达式; ...
- [Windows Server 2008] 安装IIS7.5及FTP
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装IISII ...
- 【转】npm 是干什么的
https://blog.csdn.net/zouzhigang96/article/details/79071854 网上的 npm 教程主要都在讲怎么安装.配置和使用 npm,却不告诉新人「为什么 ...
- Random同时生成多个随机数
贴一个简单示例 public DataTable selectStuInfo() { DataTable dt = new DataTable(); dt.Columns.Add("姓名&q ...
- Mysql 之主从复制,mysql-proxy读写分离
准备两台mysql服务器,master(192.168.43.64).slave(192.168.84.129) master配置: log-bin=mysql-bin binlog_format=m ...
- Ajax系列面试题总结
1.Ajax是什么?如何创建一个Ajax? Ajax并不算是一种新的技术,全称是asychronous javascript and xml,可以说是已有技术的组合,主要用来实现客户端与服务器端的异步 ...
- Django - ORM实现用户登陆
1.路由分发cmdb(app)下urls.py中,建立url与函数对应关系 2.login.html代码: 3.views.py中,login函数,确认是否登陆成功 备注:从前端 获取用户名,密码,在 ...