凸包:把给定点包围在内部的、面积最小的凸多边形。

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)

求解二维凸包并计算周长

poj1113(

id=1113">click me)

本题翻译:http://blog.csdn.net/lytning/article/details/24046075

求解二维凸包并增加一个圆的周长

计算几何 二维凸包问题 Andrew算法的更多相关文章

  1. 二维凸包 Graham扫描算法

    题目链接: http://poj.org/problem?id=1113 求下列点的凸包 求得凸包如下: Graham扫描算法: 找出最左下的点,设为一号点,将其它点对一号点连线,按照与x轴的夹角大小 ...

  2. Andrew算法求二维凸包-学习笔记

    凸包的概念 首先,引入凸包的概念: (有点窄的时候...图片右边可能会被吞,拉开图片看就可以了) 大概长这个样子: 那么,给定一些散点,如何快速地求出凸包呢(用在凸包上的点来表示凸包) Andrew算 ...

  3. 【计算几何】二维凸包——Graham's Scan法

    凸包 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内.右图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包. 一组平面上的点, ...

  4. Luogu P2742 模板-二维凸包

    Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...

  5. UVA 10652 Board Wrapping(二维凸包)

    传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组 ...

  6. 使用Graham扫描法求二维凸包的一个程序

    #include <iostream> #include <cstring> #include <cstdlib> #include <cmath> # ...

  7. luogu P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

    题解: 二维凸包裸题 按照x坐标为第一关键字,y坐标为第二关键字排序 然后相邻判断叉积用单调队列搞过去 正反都做一次就好了 代码: #include <bits/stdc++.h> usi ...

  8. 【洛谷 P2742】【模板】二维凸包

    题目链接 二维凸包板子..有时间会补总结的. #include <cstdio> #include <cmath> #include <algorithm> usi ...

  9. poj 2079 Triangle (二维凸包旋转卡壳)

    Triangle Time Limit: 3000MS   Memory Limit: 30000KB   64bit IO Format: %I64d & %I64u Submit Stat ...

随机推荐

  1. 洛谷1002 容斥原理+dfs OR DP

    //By SiriusRen #include <bits/stdc++.h> using namespace std; #define int long long ,,,,-,-,-,- ...

  2. ActiveMQ 5.10.0 安装与配置

    先在官网下载activeMQ,我这里是5.10.0. 然后在解压在一个文件夹下即可. 我这里是:D:\apache-activemq-5.10.0-bin 然后进入bin目录:D:\apache-ac ...

  3. 关于学习C语言

    c语言作为一种计算机的语言,我们学习它,有助于我们更好的了解计算机,与计算机进行交流,因此,c语言的学习对我们尤其重要. 在这个星期里,我们专业的学生在专业老师的带领下进行了c语言程序实践学习.在这之 ...

  4. [ 51Nod 1327 ] 棋盘游戏

    \(\\\) \(Description\) 给出一张\(N\times M\)的棋盘,每个格子最多放置一个棋子,一个合法的放置方案需满足: 每列至多放置一个棋子 对于第\(i\)行,前\(L_i\) ...

  5. webSocket客服在线交谈

    一>用户端 <%@ page language="java" pageEncoding="UTF-8" %><%@ taglib uri ...

  6. C# 字符串的入门

    1."@"表示字符串中的"\"不当成转义符. 2.转义符或者特殊处理的一些字符只是针对于代码中直接写出的字符串中,对于程序运行中读取出来的转义符或者特殊处理的字 ...

  7. mysql_基础2

    创建数据表:

  8. Linux 通过cksum 来判断文件是否是相同

    1. 最近scp部署文件时 发现日期会发生变化 (刚查了下 可以使用 -p 命令进行处理) 会变成部署时的日期. 不好判断文件倒是有没有部署 2. 最简单的办法 我mount了 补丁服务器  到lin ...

  9. Random同时生成多个随机数

    贴一个简单示例 public DataTable selectStuInfo() { DataTable dt = new DataTable(); dt.Columns.Add("姓名&q ...

  10. PHP 之中文转为拼音

    /** * Created by PhpStorm. * User: Administrator * Date: 2019/1/2 0002 * Time: 下午 1:01 */ class PinY ...