题目大意:

给定n个点,求面积最小的园覆盖所有点.其中\(n \leq 10^6\)

题解:

恩。。。

刚拿到这道题的时候...

什么???最小圆覆盖不是\(O(n^3)\)的随机增量算法吗?????

\(10^6\)又是个什么鬼?????????

然后去%了popoqqq大爷的题解...原来这道题数据是随机的啊。。。

随机数据有一个性质,在凸包上的点不超过\(logn\)

所以我们求凸包然后在上面跑随机增量算法即可

  1. #include <cmath>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. inline void read(int &x){
  8. x=0;char ch;bool flag = false;
  9. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  10. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  11. }
  12. inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
  13. inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
  14. const int maxn = 1000010;
  15. const double eps = 1e-9;
  16. inline int dcmp(const double &x){
  17. if(x < eps && x > -eps) return 0;
  18. return x > 0 ? 1 : -1;
  19. }
  20. struct Point{
  21. double x,y;
  22. Point(const double &a = 0,const double &b = 0){x=a;y=b;}
  23. void print(){
  24. printf("Point : (%lf,%lf)\n",x,y);
  25. }
  26. };
  27. typedef Point Vector;
  28. inline Vector operator + (const Vector &a,const Vector &b){
  29. return Vector(a.x+b.x,a.y+b.y);
  30. }
  31. inline Vector operator - (const Vector &a,const Vector &b){
  32. return Vector(a.x-b.x,a.y-b.y);
  33. }
  34. inline Vector operator / (const Vector &a,const double &b){
  35. return Vector(a.x/b,a.y/b);
  36. }
  37. inline bool operator < (const Point &a,const Point &b){
  38. return a.x == b.x ? a.y < b.y : a.x < b.x;
  39. }
  40. inline double operator * (const Vector &a,const Vector &b){
  41. return a.x*b.x + a.y*b.y;
  42. }
  43. inline double cross(const Vector &a,const Vector &b){
  44. return a.x*b.y - a.y*b.x;
  45. }
  46. inline double sqr(const double &x){
  47. return x*x;
  48. }
  49. inline double dis(const Point &a,const Point &b){
  50. return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
  51. }
  52. inline Point getPoint(const Point &p0,const Point &p1,const Point &p2){
  53. double a1 = p1.x - p0.x,b1 = p1.y - p0.y,c1 = (a1*a1 + b1*b1)/2.0;
  54. double a2 = p2.x - p0.x,b2 = p2.y - p0.y,c2 = (a2*a2 + b2*b2)/2.0;
  55. double d = a1*b2 - a2*b1;
  56. return Point(p0.x+(c1*b2-c2*b1)/d,p0.y+(a1*c2-a2*c1)/d);
  57. }
  58. Point o;double r;
  59. inline bool in_cir(const Point &p){
  60. return dcmp(dis(p,o) - r) <= 0;
  61. }
  62. Point p[maxn];int n;
  63. inline void getMinCir(){
  64. o = Point(0,0);r = 0;
  65. for(int i=2;i<=n;++i){
  66. if(!in_cir(p[i])){ o = p[i];r = 0;
  67. for(int j=1;j<i;++j){
  68. if(!in_cir(p[j])){o = (p[i]+p[j])/2.0;r = dis(p[i],o);
  69. for(int k=1;k<j;++k){
  70. if(!in_cir(p[k])){
  71. o = getPoint(p[i],p[j],p[k]);
  72. r = dis(p[i],o);
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }return;
  79. }
  80. Point ch[maxn];int m;
  81. inline void convex(){
  82. sort(p+1,p+n+1);m = 0;
  83. for(int i=1;i<=n;++i){
  84. while(m > 1 && cross(ch[m] - ch[m-1],p[i] - ch[m]) <= 0) -- m;
  85. ch[++m] = p[i];
  86. }int k = m;
  87. for(int i=n-1;i>=1;--i){
  88. while(m > k && cross(ch[m] - ch[m-1],p[i] - ch[m]) <= 0) -- m;
  89. ch[++m] = p[i];
  90. }if(n > 1) -- m;
  91. swap(n,m);swap(p,ch);
  92. }
  93. int main(){
  94. read(n);
  95. for(int i=1;i<=n;++i){
  96. scanf("%lf%lf",&p[i].x,&p[i].y);
  97. }
  98. convex();getMinCir();
  99. printf("%.2lf %.2lf %.2lf\n",o.x,o.y,r);
  100. getchar();getchar();
  101. return 0;
  102. }

bzoj 2823: [AHOI2012]信号塔 最小圆覆盖的更多相关文章

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

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

  2. 2018.07.04 BZOJ 2823: AHOI2012信号塔(最小圆覆盖)

    2823: [AHOI2012]信号塔 Time Limit: 10 Sec Memory Limit: 128 MB Description 在野外训练中,为了确保每位参加集训的成员安全,实时的掌握 ...

  3. AHOI2012 信号塔 | 最小圆覆盖模板

    题目链接:戳我 最小圆覆盖. 1.枚举第一个点,考虑当前圆是否包含了这个点,如果没有,则把圆变成以这个点为圆心,半径为0的圆. 2.枚举第二个点,考虑圆是否包含了这个点,如果没有,则把圆变成以这两个点 ...

  4. BZOJ 2823: [AHOI2012]信号塔

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2823 随机增量法.不断加点维护圆,主要是三点共圆那里打得烦(其实也就是个两中垂线求交点+联立方 ...

  5. 【BZOJ】2823: [AHOI2012]信号塔

    题意 给\(n\)个点,求一个能覆盖所有点的面积最小的圆.(\(n \le 50000\)) 分析 随机增量法 题解 理论上\(O(n^3)\)暴力,实际上加上随机化后期望是\(O(n)\)的. 算法 ...

  6. bzoj2823[AHOI2012]信号塔

    2823: [AHOI2012]信号塔 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1190  Solved: 545[Submit][Status ...

  7. 【BZOJ2823】[AHOI2012]信号塔(最小圆覆盖)

    [BZOJ2823][AHOI2012]信号塔(最小圆覆盖) 题面 BZOJ 洛谷 相同的题: BZOJ1 BZOJ2 洛谷 题解 模板题... #include<iostream> #i ...

  8. BZOJ2823 [AHOI2012]信号塔 【最小圆覆盖】

    题目链接 BZOJ2823 题解 最小圆覆盖模板 都懒得再写一次 #include<iostream> #include<cstdio> #include<cmath&g ...

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

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

随机推荐

  1. 基于jquery的bootstrap在线文本编辑器插件Summernote (转)

    Summernote是一个基于jquery的bootstrap超级简单WYSIWYG在线编辑器.Summernote非常的轻量级,大小只有30KB,支持Safari,Chrome,Firefox.Op ...

  2. python 之前函数补充(__del__, item系列, __hash__, __eq__) , 以及模块初体验

    __str__ :  str(obj) ,  需求必须实现了 __str__, 要求这个方法的返回值必须是字符串  str  类型 __repr__ (意为原型输出):  是 __str__ 的备胎( ...

  3. linux字符集查看与设置

    linux字符集查看与设置 命令:locale -a   查看本地的字符集        locale -m 查看所有支持的字符集   查看当前默认设置   echo $LANG   记录系统默认使用 ...

  4. Spring @Configuration注解

    1 该注解的用途 这个注解表示这个类可以作为spring ioc容器bean的来源,其本质上它是对xml文件中创建bean的一种替换.有了这个注释,Spring framework就能在需要的时候构造 ...

  5. php本周、本月的第一天 / 最后一天的时间

    //week $time1 = mktime(0, 0, 0, date("m"), date("d") - date("w") + 1, ...

  6. Delphi窗体研究,留个爪,以后回来研究

    Delphi - 窗体创建过程   来自大富翁. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...

  7. [luogu4755]Beautiful Pair

    [luogu4755]Beautiful Pair luogu 第一次写最大值分治感觉有点丑 每次找到最大值mid,扫小的一边,主席树查大的一边小于等于\(\frac{a[mid]}{a[i]}\)的 ...

  8. inux c编程:读写锁

    前面介绍的互斥量加锁要么是锁状态,要么就是不加锁状态.而且只有一次只有一个线程可以对其加锁.这样的目的是为了防止变量被不同的线程修改.但是如果有线程只是想读而不会去写的话,这有不会导致变量被修改.但是 ...

  9. ob 函数讲解

    ob的基本原则:如果ob缓存打开,则echo的数据首先放在ob缓存.如果是header信息,直接放在程序缓存.当页面履行到最后,会把ob缓存的数据放到程序缓存,然后依次返回给涉猎器.下面我说说ob的基 ...

  10. WORD表格数据运算技巧

    我们经常会用WORD制作表格,有时表内的数据要运算的,WORD表格数据运算能力无法与EXCEL相比.但常见的乘除加减.相邻数据累加,将金额数字自动转成大写,WORD都能在表格内自动完成.下面以一个简单 ...