题意:

给你一个由n个点构成的多边形城堡(看成二维),按顺序给你n个点,相邻两个点相连。

让你围着这个多边形城堡建一个围墙,城堡任意一点到围墙的距离要求大于等于L,让你求这个围墙的最小周长(看成二维平面)(结果四舍五入

分析:

凸包问题和这个问题的差别就在于:凸包问题没有“城堡任意一点到围墙的距离要求大于等于L”这个要求

凸包:找到一个凸多边形把这n个点形成的多边形围起来,找到的那个周长最小的凸多边形就是我们所求的凸包

那么这个问题怎么在凸包的基础上解决呢?

我们考虑L,对于求出的凸多边形,对于它的顶点X,可以证明每个X附近需要增加一定的圆弧来保证顶点到圆弧的距离大于等于L,

所有X的圆弧角度之和为Pi,将凸包平移与圆弧连接成封闭图案,最终 ans=凸包+2*Pi*L。如下图(参考:https://my.oschina.net/u/4331110/blog/4250115)

上图中黑色实线连起来的多边形就是题目给出的n个点形成的多边形

我们就是要在这个基础上满足题目“城堡任意一点到围墙的距离要求大于等于L”要求

如上图所示,也就只需要多加4段圆弧就可以满足题目需求,答案也就是ans=凸包+2*Pi*L

凸包怎么求(参考:https://www.cnblogs.com/czaoth/p/6912073.html)?

这里我们使用Graham Scan算法来实现,此算法能够在O(nlogn)的时间内找到凸包。

这里说一下二维平面下叉积的几何意义:对于二维向量a=(x1,y2)和b=(x2,y2),a×b定义为x1*y2-y1*x2。而它的几何意义就是|a||b|sin<a,b>。如果ab夹角小于180度(逆时针),那么这个值就是正值,大于180度就是负值。需要注意的是,左乘和右乘是不同的。这里给出几个例子

我认为这个sin<a,b>就是:a向量按照逆时针移动到b向量同方向的角度

Graham Scan算法过程:

Graham Scan算法的做法是先定下一个起点,一般是最左边的点和最右边的点(需要排序后选择起点),然后一个个点扫过去,如果新加入的点和之前已经找到的点所构成的“壳”凸性没有变化,就继续扫,否则就把已经找到的最后一个点删去,再比较凸性,直到凸性不发生变化。分别扫描上下两个“壳”,合并在一起,凸包就找到了。

我们找下“壳”,上下其实是一样的。首先加入两个点A和C:

然后插入第三个点G,并计算AC×CG的叉积,却发现叉积小于0,也就是说逆时针方向上∠ACG大于180度,于是删去C点,加入G点:

然后就是依照这个步骤便能加入D点。在AD上方是以D为起点。就能够找到AGD和DFEA两个凸壳。合并就得到了凸包。

关于扫描的顺序,有坐标序和极角序两种。坐标序是比较两个点的x坐标,如果小的先被扫描(扫描上凸壳的时候反过来);如果两个点x坐标相同,那么就比较y坐标,小的先被扫描(扫描上凸壳的时候也是反过来)。极角序使用arctan2函数的返回值进行比较

给出POJ1113:Wall代码:

  1. 1 #include<stdio.h>
  2. 2 #include<string.h>
  3. 3 #include<iostream>
  4. 4 #include<algorithm>
  5. 5 #include<queue>
  6. 6 #include<stack>
  7. 7 #include<map>
  8. 8 #include<math.h>
  9. 9 using namespace std;
  10. 10 const int maxn=1e3+10;
  11. 11 const double PI=acos(-1.0); //180度的弧度制
  12. 12 const double eps=1e-6;
  13. 13 struct Cpoint
  14. 14 {
  15. 15 double x,y;
  16. 16 Cpoint(){}
  17. 17 Cpoint(double xx,double yy):x(xx),y(yy){}
  18. 18 Cpoint friend operator -(Cpoint a,Cpoint b)
  19. 19 {
  20. 20 return Cpoint(a.x-b.x,a.y-b.y);
  21. 21 }
  22. 22 double friend operator ^(Cpoint a,Cpoint b)
  23. 23 {
  24. 24 return a.x*b.y-b.x*a.y;
  25. 25 }
  26. 26 bool friend operator <(Cpoint a,Cpoint b)
  27. 27 {
  28. 28 if(a.y==b.y) return a.x<b.x;
  29. 29 return a.y<b.y;
  30. 30 }
  31. 31 }point[maxn];
  32. 32 double dist(Cpoint a,Cpoint b)
  33. 33 {
  34. 34 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
  35. 35 }
  36. 36 int Sign(double x)
  37. 37 {
  38. 38 if(x>=-eps && x<=eps) return 0;
  39. 39 if(x>eps) return 1;
  40. 40 else return -1;
  41. 41 }
  42. 42 bool cmp(Cpoint a,Cpoint b)
  43. 43 {
  44. 44 int s=Sign((a-point[1])^(b-point[1]));
  45. 45 if(s>0 || (s==0 && dist(a,point[1])<dist(b,point[1]))) return 1;
  46. 46 else return 0;
  47. 47 }
  48. 48 int n,l;
  49. 49 double Graham()
  50. 50 {
  51. 51 double res=0;
  52. 52 sort(point+1,point+1+n); //得到原点(原点一般让两端的点来当)
  53. 53 sort(point+1,point+1+n,cmp); //得到积角序
  54. 54 int que[maxn],top=3;
  55. 55 que[1]=1;
  56. 56 que[2]=2;
  57. 57 que[3]=3;
  58. 58 for(int i=4;i<=n;++i)
  59. 59 { //注意下面点的顺序不要写错了
  60. 60 while(top>1 && Sign((point[que[top]]-point[que[top-1]])^(point[i]-point[que[top]]))<=0)
  61. 61 top--;
  62. 62 que[++top]=i;
  63. 63
  64. 64 }
  65. 65 for(int i=1;i<top;++i)
  66. 66 {
  67. 67 res+=dist(point[que[i]],point[que[i+1]]);
  68. 68 //printf("%.2lf**\n",res);
  69. 69 }
  70. 70 res+=dist(point[que[1]],point[que[top]]);
  71. 71 res+=2.0*PI*l;
  72. 72 return res;
  73. 73 }
  74. 74 int main()
  75. 75 {
  76. 76 while(~scanf("%d%d",&n,&l))
  77. 77 {
  78. 78 for(int i=1;i<=n;++i)
  79. 79 scanf("%lf%lf",&point[i].x,&point[i].y);
  80. 80 printf("%d\n",(int)(Graham()+0.5));
  81. 81 }
  82. 82 return 0;
  83. 83 }

POJ1113:Wall (凸包算法学习)的更多相关文章

  1. POJ1113 Wall —— 凸包

    题目链接:https://vjudge.net/problem/POJ-1113 Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submis ...

  2. POJ1113:Wall (凸包:求最小的多边形,到所有点的距离大于大于L)

    Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the ...

  3. POJ1113 Wall 凸包

    题目大意:建立围墙将城堡围起来,要求围墙至少距离城堡L,拐角处用圆弧取代,求围墙的长度. 题目思路:围墙长度=凸包周长+(2*PI*L),另外不知道为什么C++poj会RE,G++就没问题. #inc ...

  4. Graham Scan凸包算法

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

  5. POJ1113 Wall

    题目来源:http://poj.org/problem?id=1113题目大意: 如图所示,给定N个顶点构成的一个多边形和一个距离值L.建立一个围墙,把这个多边形完全包含在内,且围墙距离多边形任一点的 ...

  6. DSP算法学习-过采样技术

    DSP算法学习-过采样技术 彭会锋 2015-04-27 23:23:47 参考论文: 1 http://wr.lib.tsinghua.edu.cn/sites/default/files/1207 ...

  7. 算法学习之C语言基础

    算法学习,先熟悉一下C语言哈!!! #include <conio.h> #include<stdio.h> int main(){ printf(+); getch(); ; ...

  8. Python之路,Day21 - 常用算法学习

    Python之路,Day21 - 常用算法学习   本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...

  9. C / C++算法学习笔记(8)-SHELL排序

    原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...

随机推荐

  1. win安装python模块出现依赖问题的解决方法 & No module named 'MySqldb'

    前言 一年多了,还在写这种问题,羞愧. 新公司不让用自己的电脑,配的winPC,项目启不起来,之前也出现过这个问题,是py3缺少某个模块,但是自己没记,这次记一下好了. No module named ...

  2. Laya 踩坑日记 ---A* 导航寻路

    要做寻路,然后看了看laya 官方的例子,感觉看的一脸懵逼,早了半天的api 也没找到在哪有寻路的,最后一看代码,原来是用的github上的A星方案  https://github.com/bgrin ...

  3. 【C++】《C++ Primer 》第十八章

    第十八章 用于大型程序的工具 大规模应用程序的特殊要求包括: 在独立开发的子系统之间协同处理错误的能力. 使用各种库进行协同开发的能力. 对比较复杂的应用概念建模的能力. 一.异常处理 异常处理(ex ...

  4. Linux学习笔记 | docker基本命令

    Docker的三大核心概念:镜像.容器.仓库 镜像:类似虚拟机的镜像.用俗话说就是安装文件. 容器:类似一个轻量级的沙箱,容器是从镜像创建应用运行实例,可以将其启动.开始.停止.删除.而这些容器都是相 ...

  5. Python基础语法3-输入、输出语句

  6. 【Git】5、Git如何提交代码到远程仓库

    提交代码:如何把修改后的代码提交到远程仓库 文章目录 提交代码:如何把修改后的代码提交到远程仓库 1.同步远程代码 2.检查改动文件 3.添加文件到缓存 4.提交代码 5.推送代码 6.我的整个流程 ...

  7. 电子邮箱、邮件地址、网站地址正则表达式!几个有用的RE、regex、regexp!

    几个常用的正则表达式! r"\w[-\w\.]*@\w[-\w]*(\.\w[-\w]*)+" 这个是电子邮件地址的. r"<TAG\b[^>]*<(. ...

  8. ctfshow—pwn10

    格式化字符串漏洞 具体什么是格式化字符串请大家参考如下文章 https://wiki.x10sec.org/pwn/fmtstr/fmtstr_intro/ printf函数格式化输出符号及详细说明 ...

  9. 记录Js动态加载页面.append、html、appendChild、repend添加元素节点不生效以及解决办法

    今天再优化blog页面的时候添加了个关注按钮和图片,但是页面上这个按钮和图片时有时无,本来是搞后端的,被这个前端的小问题搞得抓耳挠腮的! 网上各种查询解决方案,把我解决问题的艰辛历程分享出来,希望大家 ...

  10. nodejs中使用worker_threads来创建新的线程

    目录 简介 worker_threads isMainThread MessageChannel parentPort和MessagePort markAsUntransferable SHARE_E ...