[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 ...
随机推荐
- \n 与 \r 在记事本中的内容表现方式 原创
总结:[0D,0A]的顺序才可以记事本才可以正常显示回车换行,其他EDITPLUS ,等编缉工具在下面三种情况下都可以换行 原始数据与表现形式 [0D,0A]序列才可以正常显示回车换行 --- ...
- Motion——shake攻略
1.子类化窗口 如果响应链中没有motionEnded:withEvent:消息的接收者,那么该消息就会被发送给应用程序的window对象.所以需要在window对象上拦截motionEnded:wi ...
- 浅谈Android自定义锁屏页的发车姿势
一.为什么需要自定义锁屏页 锁屏作为一种黑白屏时代就存在的手机功能,至今仍发挥着巨大作用,特别是触屏时代的到来,锁屏的功用被发挥到了极致.多少人曾经在无聊的时候每隔几分钟划开锁屏再关上,孜孜不倦,其酸 ...
- Android(java)学习笔记188:关于构造代码块,构造函数的一道面试题(华为面试题)
1.源码是: package text; public class TestStaticCon { public static int a = 0; static { a = 10; System.o ...
- JS实现图片宽高的等比缩放
关于图片宽高的等比缩放,其实需求就是让图片自适应父容器的宽高,并且是等比缩放图片,使图片不变形. 例如,需要实现如下的效果: 要实现上面的效果,需要知道图片的宽高,父容器的宽高,然后计算缩放后的宽高. ...
- 移动web前端小结(一)
这段时间做了几个移动项目的前端页面,姑且称之webapp.做这几个项目之前根本没接触过移动端的相关知识,以为和PC端页面没啥区别无非就是尺寸小一点罢了.上手以后发现问题颇多.下面从框架.相关知识点.遇 ...
- 黑马程序员- IO(Input- Output)(一)
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- API包: Java.io.* 缘来: java通过操作数据对象是通过流的方式来创建的 作用: ...
- c语言学习之基础知识点介绍(十):内存空间模型、地址解释及指针变量
一.内存 /* 内存: 存在内存里的. 内存分了N多个小空间,每个小空间1个字节 每个小空间有它自己的地址.每个地址之间差1 int类型占用4个字节,等于占了4个空间(有4个地址),不需要记住4个地址 ...
- 深入了解shell
接触linux很久了,但一直没有总线,老是尝鲜,什么都想学,但好多没多没有记住,特的总结了一些基本的东西,查了很多资料,不完善的方面我会慢慢的更新…… 操作系统与外部最主要的接口就叫做shell. ...
- .NET 设计模式之简单工厂模式(二)
1:建立接口 namespace Factory { public interface IPerson { } } 2:建立Worker.Student来继承IPerson接口 namespace F ...