凸包算法不难理解,写代码的时候主要是几何上的判定条件很容易写错。

算法的总体思想是:

1.给所有的点排序,找出极点(纵坐标最小的点,如果纵坐标一样,取横坐标最小的点)

2.除了极点之外,所有其他的点排序,排序的方式是与极点之间的夹角从小到大(如果夹角一样大,取距离极点近的排在前面)

3.把极点和第二个点放进栈,判断第三个点是否在这两个点的左边,如果在左边,进栈,否则,让第二个点出栈,一直进行到最后一个点

4.把所有与极点、最后一个点共线(三点一线,并且夹在两点中间)的点也放进栈里

关于栈的用法:

我原本用的是stack,但是这个容器不好取倒数第二个数,就换成了vector,用一个top变量来模拟栈顶。

在类中使用sort函数的话,自定义的比较函数不能放在类里面,否则会报错reference to non-static member function must be called: sort

vector<int> polar_point;
int polar_x, polar_y;
bool isPolar(vector<int> &a, vector<int> &b){if(a[1]==b[1]){//如果纵坐标相等,判断横坐标return a[0]<b[0];}return a[1]<b[1];//判断纵坐标
}double dist(vector<int> &a,vector<int> &b){return pow(double(pow((a[0]-b[0]),2)+pow((a[1]-b[1]),2)),0.5);
}bool smallerAngle(vector<int> &a, vector<int> &b){if(abs(atan2(a[1]-polar_y,a[0]-polar_x)-atan2(b[1]-polar_y,b[0]-polar_x))<1e-8){//这边注意不能比较浮点数是否相等,只能取一个范围return dist(a,polar_point)<dist(b,polar_point);}return atan2(a[1]-polar_y,a[0]-polar_x)<atan2(b[1]-polar_y,b[0]-polar_x);
}bool isLeft(vector<int> cur, vector<int> polar, vector<int> top){int cross = (cur[0]-polar[0])*(top[1]-polar[1])-(top[0]-polar[0])*(cur[1]-polar[1]);//x1y2-x2y1 计算叉积if(cross>0)return false;else if(cross<0)return true;else{//叉积等于0的时候,有可能是反向的,要判断一下bool codirect = ((cur[0]-polar[0])*(top[0]-polar[0]))>0||((cur[1]-polar[1])*(top[1]-polar[1]))>0;//不能只用一个坐标x来判断,x有可能是0return codirect;}
}bool isLine(vector<int> &a,vector<int> &b, vector<int> &c){bool coline = ((c[1]-a[1])*(a[0]-b[0]))==((a[1]-b[1])*(c[0]-a[0]));bool inbetween = (b[0]-a[0])*(c[0]-a[0])<0||(b[1]-a[1])*(c[1]-a[1])<0;//不能只用一个坐标x来判断,x有可能是0return coline&&inbetween;//(y3-y1)*(x1-x2)==(y1-y2)*(x3-x1) a在bc中间
}class Solution {
public:vector<vector<int>> outerTrees(vector<vector<int>>& points) {int n = points.size();//点的个数if(n==0||n==1||n==2||n==3){return points;}//简单情况直接处理sort(points.begin(),points.end(),isPolar);//排序找极点polar_point = points[0];//找到了极点polar_x = polar_point[0];polar_y = polar_point[1];sort(points.begin()+1,points.end(),smallerAngle);//基于极点排序vector<vector<int>> res;res.push_back(polar_point);int i = 1;res.push_back(points[i++]);int top = 1;while(i<n){//遍历所有的点if(isLeft(points[i],res[top-1],res[top])){//如果扫描到的点构成凸包res.push_back(points[i++]);top++;}else{//如果扫描到的点不构成凸包res.pop_back();top--;}}i = 1;while(i<n-1){//可能会漏掉的一部分点,介于极点与最后一个点之间的点,也是需要的if(isLine(points[i],points[0],points[n-1])&&find(res.begin(),res.end(),points[i])==res.end()){//要判断是否已经在答案里了res.push_back(points[i]);}i++;}return res;}
};

LeetCode 587. 安装栅栏【凸包算法】【C++】【很多坑】相关推荐

  1. D53 LeetCode 587.安装栅栏(困难)

    一.题目  二.思路(自己) 这题很好理解,但是我真的不会.(:′⌒`) 三.题解(官方) 今天我还要做康复,这题标记一下之后再写吧 安装栅栏 - 安装栅栏 - 力扣(LeetCode) (leetc ...

  2. LeetCode 587. 安装栅栏 / LintCode 1152. 安装栅栏(凸包检测:排序+叉积正负判断+正反扫描+去重)

    文章目录 1. 题目 2. 解题 1. 题目 在一个二维的花园中,有一些用 (x, y) 坐标表示的树. 由于安装费用十分昂贵,你的任务是先用最短的绳子围起所有的树. 只有当所有的树都被绳子包围时,花 ...

  3. 阿里云服务器快速安装Mysql,贴心手把手教你安装,本人踩过很多坑!(我的服务器系统CentOS 7.8 64位)

    1.先查询服务器是否安装了Mysql数据库 rpm -qa | grep mysqlrpm -e 文件名(卸载数据库,没有就跳过) 2.可以先新建一个文件夹 mkdir 文件夹名 3.下载mysql包 ...

  4. 求多边形凸包(线性算法)--陈氏凸包算法--

    http://blog.sina.com.cn/s/blog_616e189f0100qc0u.html 陈氏凸包算法-算法参考:Computing the convex hull of a simp ...

  5. Leetcode分类解析:组合算法

    Leetcode分类解析:组合算法 所谓组合算法就是指:在解决一些算法问题时,需要产生输入数据的各种组合.排列.子集.分区等等,然后逐一确认每种是不是我们要的解.从广义上来说,组合算法可以包罗万象,甚 ...

  6. java 地理围栏实现_使用Path2D和凸包算法实现地理围栏服务

    前言 地理围栏(Geo-fencing)是LBS的一种新应用,就是用一个虚拟的栅栏围出一个虚拟地理边界.在物流配送行业应用比较广,划分每个配送网点或者商家配送的范围,提高配送员的配送效率和服务的范围. ...

  7. 凸包计算几何matlab,计算几何-凸包算法 Python实现与Matlab动画演示

    凸包算法是计算几何中的最经典问题之一了.给定一个点集,计算其凸包.凸包是什么就不罗嗦了 本文给出了<计算几何--算法与应用>中一书所列凸包算法的Python实现和Matlab实现,并给出了 ...

  8. 凸包计算几何matlab,計算幾何-凸包算法 Python實現與Matlab動畫演示

    凸包算法是計算幾何中的最經典問題之一了.給定一個點集,計算其凸包.凸包是什么就不羅嗦了 本文給出了<計算幾何--算法與應用>中一書所列凸包算法的Python實現和Matlab實現,並給出了 ...

  9. matlab 凸包质心算法,求多边形凸包(线性算法)--陈氏凸包算法--Computing the convex hull of a simple polygon(源码)...

    陈氏凸包算法-算法参考:Computing the convex hull of a simple polygon 作者:Chern-Lin Chen 陈氏算法提供了一个线性效率求凸包的算法,本文使用 ...

最新文章

  1. 计算机网络(本科)形成性,《计算机组网技术》作业形考网考形成性考核-国家开放大学电大本科...
  2. [K/3Cloud]进度条控件编程接口
  3. 【Linux】一步一步学Linux——dircolors命令(239)
  4. Android之如何用dextra.ELF64查看安卓手机“设置“图标的源代码
  5. 技术人员的明天:35岁后我们做什么
  6. (转)Java线程:新特征-线程池
  7. 过滤access日志前5条数据
  8. 影响SQL server性能的关键
  9. SQLserver nText和varchar 不兼容
  10. mysql 重复最多的_MySQL查询重复出现次数最多的记录
  11. SpringCloud、RabbitMQ、Websocket集群搭建以及集群通信
  12. asp.net前端页面上使用if
  13. Image Super-Resolution via Iterative Refinement 论文解读和感想
  14. flea-db使用之基于对象池的FleaJPAQuery
  15. ds18b20温度报警C语言程序,单片机中使用DS18B20温度传感器C语言程序(参考4)
  16. 中国石油大学 现代远程教育入学指南
  17. 修改IE设置(修改注册表)允许活动内容在我的电脑的文件运行
  18. 2020考研,老学长帮你规划
  19. c2-00支持java_诺基亚双卡双待C2-00亮相
  20. 键盘钢琴(有空进来弹弹琴,真的可以弹的)

热门文章

  1. 项目奖金一般是多少_MPAcc职业发展|看看国内券商、投行、四大一年能挣多少?...
  2. 网课在线搜题公众号制作
  3. 国际图书分类号查询--国际十…
  4. WEB系列(四)_uploadfile笔记
  5. 计算机启动的四种方式,电脑有几种开机方式
  6. ThreadLocal之强、弱、软、虚引用
  7. java基础语言+面向对象_经典案例——65个
  8. python田忌赛马
  9. 惠斯登电桥传感器电路设计技巧,了解一下?
  10. -tomcat的介绍