平面凸包Graham算法
平面凸包问题是计算几何中的一个经典问题
具体就是给出平面上的多个点,求一个最小的凸多边形,使得其包含所有的点
具体形象就类似平面上有若干柱子,一个人用绳子从外围将其紧紧缠绕一圈
Graham算法##
直接讲算法
我们将所有点排序,分别求出上凸壳和下凸壳,合起来就是凸包
以上凸壳为例子,我们先将最左边的点加入凸包【可以想象,最左侧的点一定在凸包上】
之后向后查找:
1、若当前凸包内只有一点,那么加入新的点
2、如果当前凸包内不止一个点,检验新加入的点与凸包最后一个点所在直线与当前凸包最后两点坐在直线的关系
如果是这样:
满足上凸性,加入凸包
但是如果是这样:
不满足上凸性,就不加入
具体判断可以用斜率也可以用叉乘【我写斜率狂WA,还是叉乘比较滋滋】
扫过一遍,就可以得到上凸壳,下凸壳类似
复杂度\(O(nlogn)\)
hdu1348
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
using namespace std;
const int maxn = 2005,maxm = 100005;
const double INF = 1000000000000000000ll;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
const double pi = acos(-1);
struct point{double x,y;}p[maxn];
inline bool operator <(const point& a,const point& b){
return a.x == b.x ? a.y < b.y : a.x < b.x;
}
inline point operator -(const point& a,const point& b){
return (point){a.x - b.x,a.y - b.y};
}
inline double operator *(const point& a,const point& b){
return a.x * b.y - a.y * b.x;
}
inline double dis(int u,int v){
return sqrt((p[u].x - p[v].x) * (p[u].x - p[v].x) + (p[u].y - p[v].y) * (p[u].y - p[v].y));
}
int T,n,L,q[maxn],tail;
void cal(){
sort(p + 1,p + 1 + n);
q[tail = 1] = 1;
for (int i = 2; i <= n; i++){
while (tail > 1 && (p[i] - p[q[tail]]) * (p[q[tail]] - p[q[tail - 1]]) < 0) tail--;
q[++tail] = i;
}
int last = tail;
for (int i = n - 1; i; i--){
while (tail > last && (p[i] - p[q[tail]]) * (p[q[tail]] - p[q[tail - 1]]) < 0) tail--;
q[++tail] = i;
}
}
void print(){
double ans = 0;
for (int i = 1; i < tail; i++) ans += dis(q[i],q[i + 1]);
ans += 2.0 * pi * L;
if (T) printf("%.0lf\n\n",ans);
else printf("%.0lf\n",ans);
}
int main(){
T = read();
while (T--){
n = read(); L = read();
for (int i = 1; i <= n; i++) p[i].x = read(),p[i].y = read();
cal();
print();
}
return 0;
}
平面凸包Graham算法的更多相关文章
- Graham算法—二维点集VC++实现
一.凸包定义 通俗的说就是:一组平面上的点,求一个包含所有点的最小凸多边形,这个最小凸多边形就是凸包. 二.Graham算法思想 概要:Graham算法的主要思想就是,最终形成的凸包,即包围所有点的凸 ...
- Surround the Trees---hdu1392(凸包GraHam模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1392 题意:有n棵树,每棵树有一个坐标,想用一些绳子把这些树包含起来,求需要绳子的长度: 就是求凸包的 ...
- 【计算几何初步-凸包-Graham扫描法-极角序】【HDU1348】 WALL
Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- C++ 凸包生成算法
由于我的极差记忆力,我打算把这个破玩意先记下来.因为以后会有改动(Delaunay三角网生成算法),我不想把一个好的东西改坏了... 好吧-- 凸包生成算法,: 1.先在指定的宽(width)高(he ...
- HDU 5928 DP 凸包graham
给出点集,和不大于L长的绳子,问能包裹住的最多点数. 考虑每个点都作为左下角的起点跑一遍极角序求凸包,求的过程中用DP记录当前以j为当前末端为结束的的最小长度,其中一维作为背包的是凸包内侧点的数量.也 ...
- 29 基于PCL的点云平面分割拟合算法技术路线(针对有噪声的点云数据)
0 引言 最近项目中用到了基于PCL开发的基于平面的点云和CAD模型的配准算法,点云平面提取采用的算法如下. 1 基于PCL的点云平面分割拟合算法 2 参数及其意义介绍 (1)点云下采样 1. 参数: ...
- [OpenCV]基于特征匹配的实时平面目标检测算法
一直想基于传统图像匹配方式做一个融合Demo,也算是对上个阶段学习的一个总结. 由此,便采购了一个摄像头,在此基础上做了实时检测平面目标的特征匹配算法. 代码如下: # coding: utf-8 ' ...
- 二维凸包 Graham扫描算法
题目链接: http://poj.org/problem?id=1113 求下列点的凸包 求得凸包如下: Graham扫描算法: 找出最左下的点,设为一号点,将其它点对一号点连线,按照与x轴的夹角大小 ...
- 凸包Graham Scan算法实现
凸包算法实现点集合中搜索凸包顶点的功能,可以处理共线情况,可以输出共线点也可以不输出而只输出凸包顶点.经典的Graham Scan算法,点排序使用极角排序方式,并对共线情况做特殊处理.一般算法是将共线 ...
随机推荐
- SG函数入门&&HDU 1848
SG函数 sg[i]为0表示i节点先手必败. 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数.例如mex{0,1,2,4}=3. ...
- Array - Container With Most Water
/** * 此为暴力解法 * Find two lines, which together with x-axis forms a container, such that the container ...
- WINDOWS-基础:Thread.Sleep(0)
我们可能经常会用到 Thread.Sleep 函数来使线程挂起一段时间.那么你有没有正确的理解这个函数的用法呢?思考下面这两个问题: 假设现在是 2008-4-7 12:00:00.000,如果我调用 ...
- C#动态数组ArrayList
在C#中,如果需要数组的长度和元素的个数随着程序的运行不断改变,就可以使用ArrayList类,该类是一个可以动态增减成员的数组. 一.ArrayList类的常用属性和方法 1. ArrayList类 ...
- ll1文法
<program>-><external_declaration> | <program> <external_declaration> < ...
- Linux运维笔记--第四部
第四部 3. Linux扩展正则表达式实战 扩展的正则表达式:ERE(主要用于egrep或grep -E) + 重复一个或一个以上前面的字符. (*是0或多个) ? 重复0个或一个 ...
- NSXMLParser
NSXMLParser的使用 2011-05-05 15:50:17| 分类: 解析|字号 订阅 NSXMLParser解析xml格式的数据 用法如下: 首先,NSXMLParser必须继续 ...
- xmpp 协议详解
XMPP(可扩展消息处理现场协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线现场探测.它在促进服务器之间的准即时操作.这个协议可能最终允许因特网用户向因特网上的其他任何人发送 ...
- Jquery之 Ajax /json
前言: Ajax = Asynchronous JavaScript and XML(异步的JavaScript和XML) Ajax不是新的编程语言,而是一种使用现有标准的新方法. Ajax最大的优点 ...
- Mybatis查询select 传单个参数不识别,找不到
今天, Mybatis查询select 传单个参数不识别,找不到 解决办法: 加上jdbc=varchar #{XXX,jdbc=VARCHAR}