凸包真是一个神奇的算法。。


概念

  • 凸包,我理解为凸多边形
  • 叉积 对于向量AB和向量BC,记向量AB*向量BC = AB * BC * sin ∠ABC,而叉积的绝对值其实就是S△ABC/2

对于平面上的一些点,我们要求凸包上所有的点,可以使用Graham算法 时间复杂度O(nlogn)


思路

先找到最左下的点,把其他的点按叉积排序。然后维护一个堆栈,每次利用叉积和栈顶比较判断当前枚举到的点是否是凸包上的点,是则弹出栈顶元素
具体算法Click here

  • 周长
    直接所有相邻两点距离相加

  • 面积
    多边形面积直接利用公式,用叉积计算


常熟巨大的丑陋代码

# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <string.h>
# include <math.h>
# include <algorithm>
# define RG register
# define IL inline
# define ll long long
# define mem(a, b) memset(a, b, sizeof(a))
# define Min(a, b) (((a) > (b)) ? (b) : (a))
# define Max(a, b) (((a) < (b)) ? (b) : (a))
# define Sqr(a) ((a) * (a))
using namespace std; const int MAXN = 50001;
int n, top;
struct Point{
double x, y, len;
} p[MAXN], Point_A, s[MAXN]; //最左下的点
//求叉积(向量ab,向量ac)
IL double Cross(Point a, Point b, Point c){
return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
} IL double Dis(Point a, Point b){
return sqrt(Sqr(a.x - b.x) + Sqr(a.y - b.y));
}
//极角排序
IL bool Cmp(Point a, Point b){
RG double x = Cross(Point_A, a, b);
if(x > 0) return 1;
else if(x < 0) return 0;
a.len = Dis(Point_A, a);
b.len = Dis(Point_A, b);
return a.len < b.len;
}
//查找起始点,最左下
IL void Find(){
RG int temp = 0;
RG Point a = p[1];
for(RG int i = 2; i <= n; i++)
if(p[i].y < a.y || p[i].y == a.y && p[i].x < a.x){
a = p[i];
temp = i;
}
p[temp] = p[1];
p[1] = a;
Point_A = a;//保存起始点
}
//求凸包周长
IL double Length(){
RG double sum = 0;
for(RG int i = 1; i <= top; i++)
sum += Dis(s[i - 1], s[i]);
return sum;
}
//计算面积
IL double Area(){
RG double sum = 0;
for(RG int i = 1; i < top - 1; i++)
sum += Cross(s[0], s[i], s[i + 1]);
sum = fabs(sum) / 2;
return sum;
} IL void Graham(){
Find();
sort(p + 2, p + n + 1, Cmp);
s[0] = p[1]; s[1] = p[2];
for(RG int i = 3; i <= n; i++){
while(Cross(s[top - 1], s[top], p[i]) <= 0 && top) top--;
s[++top] = p[i];
}
s[++top] = p[1];
} int main(){
while(~scanf("%d", &n) && n){
top = 1;
for(RG int i = 1; i <= n; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
Graham();
cout << top << " " << length() << " " << Area() << endl;
}
return 0;
}

板子题 1.Surround the Trees HDU - 1392 2.Cows POJ - 3348

Graham凸包算法简介的更多相关文章

  1. Graham Scan凸包算法

    获得凸包的算法可以算是计算几何中最基础的算法之一了.寻找凸包的算法有很多种,Graham Scan算法是一种十分简单高效的二维凸包算法,能够在O(nlogn)的时间内找到凸包. 首先介绍一下二维向量的 ...

  2. 二维凸包 Graham扫描算法

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

  3. 凸包Graham Scan算法实现

    凸包算法实现点集合中搜索凸包顶点的功能,可以处理共线情况,可以输出共线点也可以不输出而只输出凸包顶点.经典的Graham Scan算法,点排序使用极角排序方式,并对共线情况做特殊处理.一般算法是将共线 ...

  4. POJ 2187 旋转卡壳 + 水平序 Graham 扫描算法 + 运算符重载

    水平序 Graham 扫描算法: 计算二维凸包的时候可以用到,Graham 扫描算法有水平序和极角序两种. 极角序算法能一次确定整个凸包, 但是计算极角需要用到三角函数,速度较慢,精度较差,特殊情况较 ...

  5. 圈水池 nyoj 78 凸包算法

    圈水池 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水, ...

  6. POJ1113:Wall (凸包算法学习)

    题意: 给你一个由n个点构成的多边形城堡(看成二维),按顺序给你n个点,相邻两个点相连. 让你围着这个多边形城堡建一个围墙,城堡任意一点到围墙的距离要求大于等于L,让你求这个围墙的最小周长(看成二维平 ...

  7. webrtc 的回声抵消(aec、aecm)算法简介(转)

    webrtc 的回声抵消(aec.aecm)算法简介        webrtc 的回声抵消(aec.aecm)算法主要包括以下几个重要模块:1.回声时延估计 2.NLMS(归一化最小均方自适应算法) ...

  8. AES算法简介

    AES算法简介 一. AES的结构 1.总体结构 明文分组的长度为128位即16字节,密钥长度可以为16,24或者32字节(128,192,256位).根据密钥的长度,算法被称为AES-128,AES ...

  9. openlayer的凸包算法实现

    最近在要实现一个openlayer的凸多边形,也遇到了不小的坑,就记录一下 1.具体的需求: 通过在界面点击,获取点击是的坐标点,来绘制一个凸多边形. 2.思考过程: 1)首先,我们得先获取点击事件发 ...

随机推荐

  1. 关于在jsp中的路径问题

    前言: jsp作为javaweb开发中常见的视图技术,我们平时在开发项目使用的过程中,经常会导入一些静态资源,比如css\js\jpg.png等图片格式的文件,这些文件的路径成了问题,经常会出现索引不 ...

  2. zabbix 3.4.1 解决中文乱码

    docker zabbix中文乱码 基础镜像为:zabbix/zabbix-web-nginx-mysql 1.首先下载msyh.ttf 2.docker cp msyh.ttf 容器:/usr/sh ...

  3. Ubuntu下利用Apache转发模块实现反向代理

    Apache的反向代理主要利用转发模块,proxy和proxy_http 先配置 Apache 支持proxy 和 proxy_http 在Ubuntu系统下,Apache的配置文件在目录/etc/a ...

  4. 2017年 Java 程序员,风光背后的危机

    不得不承认,经历过行业的飞速发展期,互联网的整体发展趋于平稳.为什么这么说?为什么要放在 Java 程序员的盘点下说? 的确,对于进可攻前端,后可守后端大本营的 Java 程序员而言,虽然供应逐年上涨 ...

  5. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码

    洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...

  6. Java中从键盘输入的三种方法

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ...

  7. Jenkins +git +python 进行持续集成进行接口测试(接口测试jenkins持续集成篇)

    使用jenkins+git+python脚本进行持续集成的接口测试,在jenkins平台,利用插件等,把管理代码的git仓库的代码更新下来进行持续接口测试,python进行开发测试脚本,git进行远程 ...

  8. vue.js 安装过程(转载)

      一.简介 Vue.js 是什么 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核 ...

  9. PowerDesigner 简单应用(转载)

    PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...

  10. js使用defineProperty的一些坑

    var p2={ }; Object.defineProperty(p2,"gs",{ get:function () { return this.gs; }, set:funct ...