先解释一下:这两个算法分别都是凸包问题的算法,然后Andrew是Graham的变种,速度更快,更稳定,非常优秀,介于我已经把Graham写的莫名其妙的WA了,所以我选择了这种算法!

我认为在这里,还是有必要向大家在这里先普及一下什么是凸包:


计算几何凸包

凸包:给你n个散落的点,让你求出最小的凸多边形将所有的点包括起来,或者点在边上。用到的算法是Graham或Andrew!

这里给一个链接:

Graham算法详解

下面给出Andrew算法的思路

First

首先先按照x坐标大小或y坐标大小进行排序(如果x坐标一样,y坐标就从小到大排序如果y坐标一样那么x坐标就从小到大排序)

Second

然后进入程序的主干部分,先说一下Andrew主干的大体思路,我们分两次来求这个凸包,先从左到右一遍,再从右到左一遍(或先从下到上一遍,再从上到下一遍)首先我们一定要明白第n-1个点一定会在第一遍时进入凸包栈内(看了上面链接的朋友都应该知道这个栈是如何操作的,这里不再赘述)(因为n个点是从0n-1),所以第二遍的时候不必从n-1开始,从n-20开始就可以了(代码上会有体现)然后就完了!

现在我们来详细讲一下如何实现Second的操作

我们要实现找凸包,那么就必须找到最外层的点,这里就要使用叉积进行判断(向量a叉向量b=a.x×b.y-b.x×a.y)如果为正a在b的右边反之在左边(题目中因为我们只能定义一个基准坐标系,所以为了实现这个功能我们就必须找参照点,参照点作为临时原点)代码中xmult会体现。

然后就差不多了!

下面就是代码了:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct point{
int x,y;
};
bool cmp(point a,point b)
{
if(a.y==b.y&&a.x<b.x)
return true;
else if(a.y<b.y) return true;
return false;
}
double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(b.y-a.y)*(b.y-a.y));
}
bool xcross(point a,point b,point c)
{
return (a.x-c.x)*(b.y-c.y)>=(b.x-c.x)*(a.y-c.y);
}
point node[100005];
int num[100005];
int n;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%d%d",&node[i].x,&node[i].y);
}
sort(node,node+n,cmp);
num[0]=0; num[1]=1;
int top=1;
for(int i=2;i<n;++i)
{
while(top>1&&xcross(node[i],node[num[top]],node[num[top-1]]))
top--;
top++;
num[top]=i;
}
int basic=top;
for(int i=n-2;i>=0;--i)
{
while(top>basic&&xcross(node[i],node[num[top]],node[num[top-1]]))
top--;
top++;
num[top]=i;
}
double s;
s=0.0;
for(int i=1;i<=top;++i)
{
s+=dis(node[num[i-1]],node[num[i]]);
}
printf("%.1lf",s);
return 0;
}

希望以后能够明白它的father——Gramham算法是怎么写的!

Andrew算法(我确实不懂Graham)的更多相关文章

  1. (模板)graham扫描法、andrew算法求凸包

    凸包算法讲解:Click Here 题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是 ...

  2. 计算几何 二维凸包问题 Andrew算法

    凸包:把给定点包围在内部的.面积最小的凸多边形. Andrew算法是Graham算法的变种,速度更快稳定性也更好. 首先把全部点排序.依照第一keywordx第二keywordy从小到大排序,删除反复 ...

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

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

  4. 算法模板——计算几何2(二维凸包——Andrew算法)

    实现功能:求出二维平面内一对散点的凸包(详见Codevs 1298) 很神奇的算法——先将各个点按坐标排序,然后像我们所知的那样一路左转,求出半边的凸包,然后反过来求另一半的凸包 我以前正是因为总抱着 ...

  5. Graham算法—二维点集VC++实现

    一.凸包定义 通俗的说就是:一组平面上的点,求一个包含所有点的最小凸多边形,这个最小凸多边形就是凸包. 二.Graham算法思想 概要:Graham算法的主要思想就是,最终形成的凸包,即包围所有点的凸 ...

  6. poj1113--凸包(Andrew)

    题目大意: 给出平面上若干个点的坐标,你的任务是建一个环形围墙,把所有的点围在里面,且距所有点的距离不小于l.求围墙的最小长度. 思路: 很容易得出答案就是凸包周长+以l为半径的圆的周长. 这里讲一下 ...

  7. (模板)poj1113(graham扫描法求凸包)

    题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是kuangbin的. AC code ...

  8. 分布式系统一致性算法 raft学习

    在学习MongoDB的过程中,有博客中写道其搭建复制集时使用了raft算法,经过简单地的搜索资料后,发现了一个特别好的网站资料.这个网站用动画的形式,非常清楚和详尽的解释了整个raft算法的精要和过程 ...

  9. 受限玻尔兹曼机(RBM)学习笔记(七)RBM 训练算法

      去年 6 月份写的博文<Yusuke Sugomori 的 C 语言 Deep Learning 程序解读>是囫囵吞枣地读完一个关于 DBN 算法的开源代码后的笔记,当时对其中涉及的算 ...

随机推荐

  1. Logrotate工具使用

    Logrotate ​ logrotate是一个被设计来简化系统管理日志文件的工具,在系统运行时,如果产生大量的日志文件,可以使用该工具进行管理,如/var/log/*文件夹是存储系统和应用日志的目录 ...

  2. Spark Streaming处理Flume数据练习

    把Flume Source(netcat类型),从终端上不断给Flume Source发送消息,Flume把消息汇集到Sink(avro类型),由Sink把消息推送给Spark Streaming并处 ...

  3. (十六)re模块

    正则表达式并不是Python的一部分,本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言.正则表达式是用于处理字符串的强大工具,很多编程语言都支持正则表达式的语法. 字符匹配分为普通字 ...

  4. 【Oracle】表空间配额问题

    由于需求,需要新建用户,但是新建的用户,会有相关的配额跟着,莫名其妙的问题让人很头疼 下面介绍下如何修改成不限制配额 select * from user_ts_quotas ; alter user ...

  5. 当spring 对象@Autowired 注入失败或者创建对象Bean失败、No qualifying bean/Error creating bean 的失败情形分析和解决方案

    错误信息 今天开发的过程中突然出现如下错误: Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: N ...

  6. 快速查询表中的NULL数据

    正常情况下,NULL值是不会放入B-TREE索引的,因此根据IS NULL查询的时候走的通常是全表扫描,如果记录比较少还好,记录比较多,查询会非常耗时 可以通过创建一个索引来解决 CREATE IND ...

  7. 鸿蒙的远程交互组件应用及微信小程序的远程交互组件应用

    注:鸿蒙的远程交互组件应用相对复杂 ,访问网络时,首先要配置网络权限,华为官方文档有问题,在此引用我老师配置的模板,见附件 过程:1.导入鸿蒙的网络请求模块fetch 2.发起对服务器的请求(在这过程 ...

  8. 安装jdk-windows系统

    1. 明确需要安装的jdk版本,注意jdk存在小版本号,例如jdk1.7_51,如果不清楚小版本号的话建议安装最新版本的jdk: 2. 打开cmd命令窗口,输入java -version查看本机是否安 ...

  9. Samba共享工具安装

    Samba 是一种在局域网上共享文件的一种通信协议,它为局域网内的不同计算机之间提供文件的共享服务. (1)下载并安装 Samba 工具. 确定 Ubuntu 已连接到互联网, 执行如下命令下载 Sa ...

  10. Markdown 编辑器+同步预览+文件笔记管理+静态博客 metadata 管理

    Leanote: 1. 笔记管理, 支持富文本, markdown, 写作模式.... 编辑器绝对好用. 另外特意为coder制作了一个贴代码的插件, 真是太贴心(因为作者也是coder) 2. 博客 ...