[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 ...
随机推荐
- 如何调试PHP的Core之获取基本信息 --------风雪之隅 PHP7核心开发者
http://www.laruence.com/2011/06/23/2057.html https://github.com/laruence PHP开发组成员, Zend兼职顾问, PHP7核心开 ...
- hdu2044java递推
一只小蜜蜂... Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- PS之放射背景
效果图 素材 新建图层,填充颜色 新建图层,矩形工具画条形 滤镜-扭曲-极坐标 合并图层,效果如下 新建图层,画一个适当的圆 滤镜-模糊-高斯模糊 将素材人物抠出来放在中间
- 基于shiro授权过程
1.对subject进行授权,调用方法isPermitted("permission串")2.SecurityManager执行授权,通过ModularRealmAuthorize ...
- Java Map集合按照key和value排序之法
一.理论基点 Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等. TreeMap:基于红黑树(Red-Black-Tre ...
- Oracle中的rownum,ROWID的 用法
1.ROWNUM的使用——TOP-N分析 使用SELECT语句返回的结果集,若希望按特定条件查询前N条记录,可以使用伪列ROWNUM. ROWNUM是对结果集加的一个伪列,即先查到结果集之后再加上去的 ...
- iOS-UI控件精讲之UIView
道虽迩,不行不至:事虽小,不为不成. 相关阅读 1.iOS-UI控件精讲之UIView(本文) 2.iOS-UI控件精讲之UILabel ...待续 UIView是所有UI控件的基类,在布局的时候通常 ...
- CoreAnimation4-隐式动画和显式动画
事务 Core Animation基于一个假设,说屏幕上的任何东西都可以(或者可能)做动画.动画并不需要你在Core Animation中手动打开,相反需要明确地关闭,否则他会一直存在. 当你改变CA ...
- 原生Javascript实现控制DIV属性
写在前面: 从事前端工作已有一年之久,因为工作的性质,不太涉及JS方面,所以自己的JS水平一直处于小白阶段,工作闲暇之余,在网上找了一些小项目,希望练练手,促进自己成长.这是第一篇,后续还会有很多记录 ...
- SQL70001: This statement is not recognized in this context.
关于错误: SQL70001: This statement is not recognized in this context. 的产生原因以及解决办法. 在SQL Server Databas ...