题目链接:BZOJ - 1336

题目分析

最小圆覆盖有一个算法叫做随机增量法,看起来复杂度像是 O(n^3) ,但是可以证明其实平均是 O(n) 的,至于为什么我不知道= =

为什么是随机呢?因为算法进行前要将所有的点 random_shuffle 一次。为什么要这样做呢?因为这样就可以防止出题人用最坏情况卡掉增量算法。

这和随机化快排使用随机是一个道理。

算法步骤:

  1. random_shuffle n 个点
  2. 将圆设定为以 P[1] 为圆心,以 0 为半径
  3. for i : 1 to n
  4. {
  5. if (P[i] 不在圆内)
  6. {
  7. 将圆设定为以 P[i] 为圆心,以 0 为半径
  8. for j : 1 to i - 1
  9. {
  10. if (P[j] 不在圆内)
  11. {
  12. 将圆设定为以 P[i]P[j] 为直径
  13. for k : 1 to j - 1
  14. {
  15. if (P[k] 不在圆内)
  16. {
  17. 将圆设定为 P[i],P[j],P[k] 的外接圆
  18. }
  19. }
  20. }
  21. }
  22. }
  23. }

  

代码

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <cmath>
  6. #include <algorithm>
  7.  
  8. using namespace std;
  9.  
  10. #define Vector Point
  11.  
  12. typedef double LF;
  13.  
  14. const int MaxN = 100000 + 5;
  15.  
  16. const LF Eps = 1e-12;
  17.  
  18. int n;
  19.  
  20. struct Point
  21. {
  22. LF x, y;
  23. Point() {}
  24. Point(LF a, LF b)
  25. {
  26. x = a; y = b;
  27. }
  28. } P[MaxN];
  29.  
  30. Point operator + (Point p1, Point p2)
  31. {
  32. return Point(p1.x + p2.x, p1.y + p2.y);
  33. }
  34. Point operator - (Point p1, Point p2)
  35. {
  36. return Point(p1.x - p2.x, p1.y - p2.y);
  37. }
  38. Vector operator * (Vector v, LF t)
  39. {
  40. return Vector(v.x * t, v.y * t);
  41. }
  42. Vector operator / (Vector v, LF t)
  43. {
  44. return Vector(v.x / t, v.y / t);
  45. }
  46.  
  47. inline LF Sqr(LF x) {return x * x;}
  48. inline LF gmax(LF a, LF b) {return a > b ? a : b;}
  49.  
  50. inline LF Dis(Point p1, Point p2)
  51. {
  52. return sqrt(Sqr(p1.x - p2.x) + Sqr(p1.y - p2.y));
  53. }
  54.  
  55. struct Circle
  56. {
  57. Point o;
  58. LF r;
  59. Circle() {}
  60. Circle(Point a, LF b)
  61. {
  62. o = a; r = b;
  63. }
  64. bool Inside(Point p)
  65. {
  66. return Dis(p, o) - r <= Eps;
  67. }
  68. } C;
  69.  
  70. struct Line
  71. {
  72. Point p;
  73. Vector v;
  74. Line() {}
  75. Line(Point a, Vector b)
  76. {
  77. p = a; v = b;
  78. }
  79. } L1, L2;
  80.  
  81. LF Cross(Vector v1, Vector v2)
  82. {
  83. return v1.x * v2.y - v2.x * v1.y;
  84. }
  85.  
  86. Point Intersection(Line l1, Line l2)
  87. {
  88. Vector u = l2.p - l1.p;
  89. LF t = Cross(l2.v, u) / Cross(l2.v, l1.v);
  90. return l1.p + (l1.v * t);
  91. }
  92.  
  93. Vector Change(Vector v)
  94. {
  95. return Vector(-v.y, v.x);
  96. }
  97.  
  98. Line Verticle(Point p1, Point p2)
  99. {
  100. Line ret;
  101. ret.p = (p1 + p2) / 2.0;
  102. ret.v = Change(p2 - p1);
  103. return ret;
  104. }
  105.  
  106. int main()
  107. {
  108. srand(19981014);
  109. scanf("%d", &n);
  110. for (int i = 1; i <= n; ++i)
  111. scanf("%lf%lf", &P[i].x, &P[i].y);
  112. random_shuffle(P + 1, P + n + 1);
  113. C.o = P[1];
  114. C.r = 0;
  115. for (int i = 1; i <= n; ++i)
  116. {
  117. if (C.Inside(P[i])) continue;
  118. C.o = P[i]; C.r = 0;
  119. for (int j = 1; j < i; ++j)
  120. {
  121. if (C.Inside(P[j])) continue;
  122. C.o = (P[i] + P[j]) / 2.0;
  123. C.r = Dis(C.o, P[j]);
  124. for (int k = 1; k < j; ++k)
  125. {
  126. if (C.Inside(P[k])) continue;
  127. L1 = Verticle(P[i], P[k]);
  128. L2 = Verticle(P[j], P[k]);
  129. C.o = Intersection(L1, L2);
  130. C.r = Dis(C.o, P[k]);
  131. }
  132. }
  133. }
  134. printf("%.10lf\n%.10lf %.10lf\n", C.r, C.o.x, C.o.y);
  135. return 0;
  136. }

  

[BZOJ 1336] [Balkan2002] Alien最小圆覆盖 【随机增量法】的更多相关文章

  1. 【BZOJ1336】[Balkan2002]Alien最小圆覆盖 随机增量法

    [BZOJ1336][Balkan2002]Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=10000 ...

  2. 【bzoj1336/1337/2823】[Balkan2002]Alien最小圆覆盖 随机增量法

    题目描述 给出N个点,让你画一个最小的包含所有点的圆. 输入 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000. ...

  3. Bzoj 1336&1337 Alien最小圆覆盖

    1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 Sec  Memory Limit: 162 MBSec  Special Judge Submit: 1473  ...

  4. BZOJ 1337: 最小圆覆盖1336: [Balkan2002]Alien最小圆覆盖(随机增量法)

    今天才知道有一种东西叫随机增量法就来学了= = 挺神奇的= = A.令ci为包括前i个点的最小圆,若第i+1个点无法被ci覆盖,则第i+1个点一定在ci+1上 B.令ci为包括前i个点的最小圆且p在边 ...

  5. BZOJ.2823.[AHOI2012]信号塔(最小圆覆盖 随机增量法)

    BZOJ 洛谷 一个经典的随机增量法,具体可以看这里,只记一下大体流程. 一个定理:如果一个点\(p\)不在点集\(S\)的最小覆盖圆内,那么它一定在\(S\bigcup p\)的最小覆盖圆上. 所以 ...

  6. 【BZOJ】1336: [Balkan2002]Alien最小圆覆盖

    题解 我们先把所有点random_shuffle一下 然后对前i - 1个点计算一个最小圆覆盖,然后第i个点如果不在这个圆里,那么我们把这个点当成一个新的点,作为圆心,半径为0 从头枚举1 - i - ...

  7. bzoj2823: [AHOI2012]信号塔&&1336: [Balkan2002]Alien最小圆覆盖&&1337: 最小圆覆盖

    首先我写了个凸包就溜了 这是最小圆覆盖问题,今晚学了一下 先随机化点,一个个加入 假设当前圆心为o,半径为r,加入的点为i 若i不在圆里面,令圆心为i,半径为0 再重新从1~i-1不停找j不在圆里面, ...

  8. [BZOJ2823][BZOJ1336][BZOJ1337]最小圆覆盖(随机增量法)

    算法介绍网上有很多,不解释了. 给出三点坐标求圆心方法:https://blog.csdn.net/liyuanbhu/article/details/52891868 记得先random_shuff ...

  9. hdu 3007【最小圆覆盖-随机增量法模板】

    #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> usin ...

随机推荐

  1. 谷歌google搜索打不开、谷歌gmail邮箱及相关服务无法登录的解决的方法

    歌打不开 google打不开,与中国大陆封杀有关,可是主要是由于近期googleserver在全球范围内又一次进行了布局调整. 解决的方法是仅仅要改动用户本地计算机hosts文件就能够了. 一.Win ...

  2. the Linux Kernel: Traffic Control, Shaping and QoS

    −Table of Contents Journey to the Center of the Linux Kernel: Traffic Control, Shaping and QoS 1 Int ...

  3. Xcode 5 安装coco2d-iphone

    从http://www.cocos2d-iphone.org/download/下载并解压缩最新版本的cocos2d,默认情况下会保存在 /Users/XXX/Downloads/cocos2d-ip ...

  4. 如何设计一个更好的C++ ORM

    2016/11/26 "用C++的方式读写数据库,简直太棒了!" 上一篇相关文章:如何设计一个简单的C++ ORM (旧版代码)

  5. (转)一个form表单实现提交多个action

    方法一: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4 ...

  6. Bootstrap--全局CSS样式之概览

    (1)HTML5文档类型 Bootstrap 使用到的某些 HTML 元素和 CSS 属性需要将页面设置为 HTML5 文档类型.在项目中的每个页面都要参照下面的格式进行设置. Code<!DO ...

  7. jquery mobile入门资料

    由于项目中用到了,就去看了一下视频,然后进一步的找找资源,最后自己再总结一遍!(就是动手操作一遍,不论你感觉多简单,只有动手之后,你才有可能有收获) 当然如果你喜欢看文档可以到官网仔细研究,不过喜欢快 ...

  8. UML图基本类型

    use case model用例模型 analysiss model分析模型 design model设计模型 implementation model实现模型 deployment model部署模 ...

  9. IIS配置不正确可能导致“远程服务器返回错误: (404) 未找到"错误一例。

    今天上传附件出现了下图所示的问题: 查找百度发现http://www.cnblogs.com/chuncn/archive/2009/09/08/1562759.html 文中提的比较靠谱. 但是,设 ...

  10. Canvas保存图片保存到本地

    使用Canvas绘图,将图片保存到本地方法 一.使用HTML5 a标签的download属性,将图片保存到本地,不需要链接服务器 关于download属性:HTML5 <a>标签downl ...