[BZOJ 1336] [Balkan2002] Alien最小圆覆盖 【随机增量法】
题目链接:BZOJ - 1336
题目分析
最小圆覆盖有一个算法叫做随机增量法,看起来复杂度像是 O(n^3) ,但是可以证明其实平均是 O(n) 的,至于为什么我不知道= =
为什么是随机呢?因为算法进行前要将所有的点 random_shuffle 一次。为什么要这样做呢?因为这样就可以防止出题人用最坏情况卡掉增量算法。
这和随机化快排使用随机是一个道理。
算法步骤:
- random_shuffle n 个点
- 将圆设定为以 P[1] 为圆心,以 0 为半径
- for i : 1 to n
- {
- if (P[i] 不在圆内)
- {
- 将圆设定为以 P[i] 为圆心,以 0 为半径
- for j : 1 to i - 1
- {
- if (P[j] 不在圆内)
- {
- 将圆设定为以 P[i]P[j] 为直径
- for k : 1 to j - 1
- {
- if (P[k] 不在圆内)
- {
- 将圆设定为 P[i],P[j],P[k] 的外接圆
- }
- }
- }
- }
- }
- }
代码
- #include <iostream>
- #include <cstdlib>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- using namespace std;
- #define Vector Point
- typedef double LF;
- const int MaxN = 100000 + 5;
- const LF Eps = 1e-12;
- int n;
- struct Point
- {
- LF x, y;
- Point() {}
- Point(LF a, LF b)
- {
- x = a; y = b;
- }
- } P[MaxN];
- Point operator + (Point p1, Point p2)
- {
- return Point(p1.x + p2.x, p1.y + p2.y);
- }
- Point operator - (Point p1, Point p2)
- {
- return Point(p1.x - p2.x, p1.y - p2.y);
- }
- Vector operator * (Vector v, LF t)
- {
- return Vector(v.x * t, v.y * t);
- }
- Vector operator / (Vector v, LF t)
- {
- return Vector(v.x / t, v.y / t);
- }
- inline LF Sqr(LF x) {return x * x;}
- inline LF gmax(LF a, LF b) {return a > b ? a : b;}
- inline LF Dis(Point p1, Point p2)
- {
- return sqrt(Sqr(p1.x - p2.x) + Sqr(p1.y - p2.y));
- }
- struct Circle
- {
- Point o;
- LF r;
- Circle() {}
- Circle(Point a, LF b)
- {
- o = a; r = b;
- }
- bool Inside(Point p)
- {
- return Dis(p, o) - r <= Eps;
- }
- } C;
- struct Line
- {
- Point p;
- Vector v;
- Line() {}
- Line(Point a, Vector b)
- {
- p = a; v = b;
- }
- } L1, L2;
- LF Cross(Vector v1, Vector v2)
- {
- return v1.x * v2.y - v2.x * v1.y;
- }
- Point Intersection(Line l1, Line l2)
- {
- Vector u = l2.p - l1.p;
- LF t = Cross(l2.v, u) / Cross(l2.v, l1.v);
- return l1.p + (l1.v * t);
- }
- Vector Change(Vector v)
- {
- return Vector(-v.y, v.x);
- }
- Line Verticle(Point p1, Point p2)
- {
- Line ret;
- ret.p = (p1 + p2) / 2.0;
- ret.v = Change(p2 - p1);
- return ret;
- }
- int main()
- {
- srand(19981014);
- scanf("%d", &n);
- for (int i = 1; i <= n; ++i)
- scanf("%lf%lf", &P[i].x, &P[i].y);
- random_shuffle(P + 1, P + n + 1);
- C.o = P[1];
- C.r = 0;
- for (int i = 1; i <= n; ++i)
- {
- if (C.Inside(P[i])) continue;
- C.o = P[i]; C.r = 0;
- for (int j = 1; j < i; ++j)
- {
- if (C.Inside(P[j])) continue;
- C.o = (P[i] + P[j]) / 2.0;
- C.r = Dis(C.o, P[j]);
- for (int k = 1; k < j; ++k)
- {
- if (C.Inside(P[k])) continue;
- L1 = Verticle(P[i], P[k]);
- L2 = Verticle(P[j], P[k]);
- C.o = Intersection(L1, L2);
- C.r = Dis(C.o, P[k]);
- }
- }
- }
- printf("%.10lf\n%.10lf %.10lf\n", C.r, C.o.x, C.o.y);
- return 0;
- }
[BZOJ 1336] [Balkan2002] Alien最小圆覆盖 【随机增量法】的更多相关文章
- 【BZOJ1336】[Balkan2002]Alien最小圆覆盖 随机增量法
[BZOJ1336][Balkan2002]Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=10000 ...
- 【bzoj1336/1337/2823】[Balkan2002]Alien最小圆覆盖 随机增量法
题目描述 给出N个点,让你画一个最小的包含所有点的圆. 输入 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000. ...
- Bzoj 1336&1337 Alien最小圆覆盖
1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 Sec Memory Limit: 162 MBSec Special Judge Submit: 1473 ...
- BZOJ 1337: 最小圆覆盖1336: [Balkan2002]Alien最小圆覆盖(随机增量法)
今天才知道有一种东西叫随机增量法就来学了= = 挺神奇的= = A.令ci为包括前i个点的最小圆,若第i+1个点无法被ci覆盖,则第i+1个点一定在ci+1上 B.令ci为包括前i个点的最小圆且p在边 ...
- BZOJ.2823.[AHOI2012]信号塔(最小圆覆盖 随机增量法)
BZOJ 洛谷 一个经典的随机增量法,具体可以看这里,只记一下大体流程. 一个定理:如果一个点\(p\)不在点集\(S\)的最小覆盖圆内,那么它一定在\(S\bigcup p\)的最小覆盖圆上. 所以 ...
- 【BZOJ】1336: [Balkan2002]Alien最小圆覆盖
题解 我们先把所有点random_shuffle一下 然后对前i - 1个点计算一个最小圆覆盖,然后第i个点如果不在这个圆里,那么我们把这个点当成一个新的点,作为圆心,半径为0 从头枚举1 - i - ...
- bzoj2823: [AHOI2012]信号塔&&1336: [Balkan2002]Alien最小圆覆盖&&1337: 最小圆覆盖
首先我写了个凸包就溜了 这是最小圆覆盖问题,今晚学了一下 先随机化点,一个个加入 假设当前圆心为o,半径为r,加入的点为i 若i不在圆里面,令圆心为i,半径为0 再重新从1~i-1不停找j不在圆里面, ...
- [BZOJ2823][BZOJ1336][BZOJ1337]最小圆覆盖(随机增量法)
算法介绍网上有很多,不解释了. 给出三点坐标求圆心方法:https://blog.csdn.net/liyuanbhu/article/details/52891868 记得先random_shuff ...
- hdu 3007【最小圆覆盖-随机增量法模板】
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> usin ...
随机推荐
- 谷歌google搜索打不开、谷歌gmail邮箱及相关服务无法登录的解决的方法
歌打不开 google打不开,与中国大陆封杀有关,可是主要是由于近期googleserver在全球范围内又一次进行了布局调整. 解决的方法是仅仅要改动用户本地计算机hosts文件就能够了. 一.Win ...
- 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 ...
- Xcode 5 安装coco2d-iphone
从http://www.cocos2d-iphone.org/download/下载并解压缩最新版本的cocos2d,默认情况下会保存在 /Users/XXX/Downloads/cocos2d-ip ...
- 如何设计一个更好的C++ ORM
2016/11/26 "用C++的方式读写数据库,简直太棒了!" 上一篇相关文章:如何设计一个简单的C++ ORM (旧版代码)
- (转)一个form表单实现提交多个action
方法一: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4 ...
- Bootstrap--全局CSS样式之概览
(1)HTML5文档类型 Bootstrap 使用到的某些 HTML 元素和 CSS 属性需要将页面设置为 HTML5 文档类型.在项目中的每个页面都要参照下面的格式进行设置. Code<!DO ...
- jquery mobile入门资料
由于项目中用到了,就去看了一下视频,然后进一步的找找资源,最后自己再总结一遍!(就是动手操作一遍,不论你感觉多简单,只有动手之后,你才有可能有收获) 当然如果你喜欢看文档可以到官网仔细研究,不过喜欢快 ...
- UML图基本类型
use case model用例模型 analysiss model分析模型 design model设计模型 implementation model实现模型 deployment model部署模 ...
- IIS配置不正确可能导致“远程服务器返回错误: (404) 未找到"错误一例。
今天上传附件出现了下图所示的问题: 查找百度发现http://www.cnblogs.com/chuncn/archive/2009/09/08/1562759.html 文中提的比较靠谱. 但是,设 ...
- Canvas保存图片保存到本地
使用Canvas绘图,将图片保存到本地方法 一.使用HTML5 a标签的download属性,将图片保存到本地,不需要链接服务器 关于download属性:HTML5 <a>标签downl ...