[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 ...
随机推荐
- 软件项目量化管理(CMMI高成熟度)实践经验谈——之项目管理过程策划篇
续:软件项目量化管理(CMMI高成熟度)实践经验谈--之概述篇 二.项目管理过程 软件开发项目管理过程,从项目全视角来看,分为售前.售中.售后等三个大的阶段.本文所谈的是售中阶段项目管理过程,在售中阶 ...
- C和指针 (pointers on C)——第四章:语句(上)
第四章--语句(上) 总结总结!!! C没有布尔类型,所以在一些逻辑推断时候必须用整型表达式,零值为假,非零值为真. for比while把控制循环的表达式收集起来放在一个地方,以便寻找. do语句比w ...
- tty、pty、pts等(小记)
http://blog.csdn.net/dbzhang800/article/details/6939742 1> tty(终端设备的统称):tty一词源于Teletypes,或者telety ...
- android 6.0获取 WRITE_SETTINGS 权限
android 6.0上只写在AndroidManifest中是不行的,还必须手动打开才行 private void setBrightnessMode(Context context, int mo ...
- 删除mysql重复记录的办法
网上有很多的办法,但是大多数都是通过临时表的办法,其实你是可以用一句简单的sql就可以做到: alter ignore table SOMETABLE add primary key(fields n ...
- tableview 在ios8上面分割线不全的问题
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath ...
- jQuery 选择器【1】
jQuery 选择器 请使用我们的 jQuery 选择器检测器 来演示不同的选择器. 选择器 实例 选取 * $("*") 所有元素 #id $("#lastname&q ...
- 【转载】介绍“Razor”— ASP.NET的一个新视图引擎
最近在做一个项目,用的MVC razor 视图,因为之前没用这个视图做过,于是查阅文档资料,共享一下. https://msdn.microsoft.com/zh-cn/ff849693 内容主要是讲 ...
- javascript 浏览器执行断点
在javascript代码里面有个语句可以让浏览器执行到这里的时候触发断点,这个命令就是 debugger 很好用
- js作用域链
js作用域链 <script> var up = 555; function display(){ var innerVar = 2; function inner(){ var inne ...