题目链接:

http://poj.org/problem?id=1113

求下列点的凸包

求得凸包如下:

Graham扫描算法:

找出最左下的点,设为一号点,将其它点对一号点连线,按照与x轴的夹角大小排序:

让点1,2入栈,从第三个点开始循环

步骤1:判断该点是否在栈顶第二个点和栈顶的点的连线的左边,

2.如果在左边,将该点入栈,继续循环,

3.如果不在,弹出栈顶点,重复步骤1,

3在1,2连线左边,3入栈

4在2,3连线左边,4入栈

5不在3,4连线左边,4出栈,5在2,3连线左边,5入栈

6在3,5连线左边,6入栈

7不在5,6连线左边,6出栈,7在3,5连线左边,7入栈

遍历完成后,将栈顶与1连起来就完成了

代码

  1. //#include<bits/stdc++.h>
  2. #include<iostream>
  3. #include<cmath>
  4. #include<algorithm>
  5. #define fi first
  6. #define se second
  7. #define INF 0x3f3f3f3f
  8. #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
  9. #define pqueue priority_queue
  10. #define NEW(a,b) memset(a,b,sizeof(a))
  11. #define lowbit(x) ((x)&(-x))
  12. using namespace std;
  13. const double pi=4.0*atan(1.0);
  14. const double e=exp(1.0);
  15. const int maxn=4e4+;
  16. typedef long long LL;
  17. typedef unsigned long long ULL;
  18. const LL mod=1e9+;
  19. const ULL base=1e7+;
  20. struct Point{
  21. int x,y;
  22. bool operator<(Point &u){//坐标排序
  23. if(x!=u.x) return x<u.x;
  24. return y<u.y;
  25. }
  26. };
  27. Point vex[maxn],Stack[maxn],Basis;
  28. short checkL(Point p,Point q,Point s){//判断点s是否在直线pq的左侧
  29. int area2=p.x*q.y-p.y*q.x+q.x*s.y-q.y*s.x+s.x*p.y-s.y*p.x;
  30. if(area2>) return ;//表示在左侧
  31. if(area2==) return ;//表示在同一条线上;
  32. return -;//表示在右侧
  33. }
  34. double dis(Point u,Point v){//计算uv的距离
  35. return sqrt((u.x-v.x)*(u.x-v.x)*1.0+(u.y-v.y)*(u.y-v.y));
  36. }
  37. bool cmp(Point a,Point b){//极角排序
  38. short m=checkL(Basis,a,b);
  39. if(m==) return ;//b在基点与a的连线的左侧,说明b的极角大于a
  40. if(m==&&dis(Basis,a)<=dis(Basis,b))//极角相同时,靠近基点的排在前
  41. return ;
  42. return ;
  43. }
  44. int main(){
  45. cin.tie();
  46. cout.tie();
  47. int n,l;
  48. cin>>n>>l;
  49. for(int i=;i<n;i++){
  50. cin>>vex[i].x>>vex[i].y;
  51. }
  52. sort(vex,vex+n);
  53. Basis=vex[];//选第一个点为基点
  54. sort(vex+,vex+n,cmp);
  55. int top=;
  56. Stack[top]=vex[];
  57. Stack[++top]=vex[];
  58. for(int i=;i<n;i++){
  59. while(top>=&&checkL(Stack[top-],Stack[top],vex[i])<){
  60. top--;
  61. }
  62. Stack[++top]=vex[i];
  63. }
  64. double sum=0.0;
  65. for(int i=;i<top;i++){
  66. sum+=dis(Stack[i],Stack[i+]);
  67. }
  68. sum+=dis(Stack[top],Stack[]);
  69. sum+=2.0*pi*l;
  70. LL ans=(LL)sum;
  71. if(sum-(double)ans>=0.5){
  72. ans++;
  73. }
  74. cout<<ans<<endl;
  75. system("pause");
  76. return ;
  77. }

二维凸包 Graham扫描算法的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. Luogu P2742 模板-二维凸包

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

  7. android 二维码生成+扫描

    android 二维码生成+扫描 1.在Android应用当中,很多时候都要用到二维码扫描,来避免让用户手动输入的麻烦. Google官方自己推出了一个二维码开源项目:ZXing库. 2.这里简单介绍 ...

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

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

  9. ios中二维码的使用之二: 二维码的扫描

    二维码的扫描: 1,导入支持框架,<AVFoundation/AVFoundation.h> 2 ,扫描:

随机推荐

  1. linux 命令失效

    失效的原因 是我在执行命令的时候输入错误了.在网上找了很多的办法都是以下两种方式:  其一:直接在linux命令行界面输入如下,然后回车(导入环境变量,以及shell常见的命令的存放地址):  exp ...

  2. vue调用支付接口

    html: <div class="paymentHtml" v-html="paymentHtml"></div> script: d ...

  3. XML二

    XML的语法要求: 1,XML文档必须有一个顶层元素,即文档元素,所有其他元素必须嵌入在文档元素中. 2,元素嵌套要正确,即如果一个元素在另一个元素中开始,那么必须在同一个元素中结束. 3,每个元素必 ...

  4. Processing 编程学习指南 (丹尼尔·希夫曼 著)

    https://processing.org/reference/ 第1章 像素 (已看) 第2章 Processing (已看) 第3章 交互 (已看) 第4章 变量 (已看) 第5章 条件语句 ( ...

  5. centos7以rpm方法装mysql5.7及大坑

    环境: CentOS Linux release 7.5.1804 (Core)   Mysql版本: MySQL-5.7.17-1.el6.x86_64.rpm-bundle.tar   下载地址( ...

  6. windos下安装django

    一:pip install Django       安装完以后,运行python manager.py runserver 0.0.0.0:8000报错:   1):没有安装Mysql-python ...

  7. exactly-once和kafka

    Exactly-Once的概念是指"恰好一次",简单讲就是同一个数据只会被处理一次,应用有机质保证不会重复处理同一条数据(如果数据因为因为网络业务异常被发送多次):Exactly- ...

  8. Java面试题 Web+EJB & Spring+数据结构& 算法&计算机基础

    六.Web 部分:(共题:基础40 道,基础37 道,中等难度3 道) 122.说出Servlet 的生命周期,并说出Servlet 和CGI 的区别? [基础] 答:Web 容器加载Servlet ...

  9. sync;sync;sync;reboot

    Sync命令 在用reboot命令启动unix系统后,系统提示出错信息,部分应用程序不能正常工作.经仔细检查系统文件,并和初始的正确备份进行比较,发现某些文件确实被破坏了,翻来覆去找不到文件遭破坏的原 ...

  10. Git分支merge和rebase的区别

    Git merge是用来合并两个分支的. git merge b # 将b分支合并到当前分支 同样 git rebase b,也是把 b分支合并到当前分支 原理 如下: 假设你现在基于远程分支&quo ...