题目描述:

给出平面上N个点,请求出一个半径最小的圆覆盖住所有的点

输入:

第一行给出数字N,现在N行,每行两个实数x,y表示其坐标.

输出:

输出最小半径,输出保留三位小数.

样例输入:

4
1 0
0 1
0 -1
-1 0

样例输出:
1.000

题解:

随机增量法大法好呀!!!看起来是O(n^3)的算法,实际上期望是O(n)的。

具体操作如下:

(1)把点的顺序打乱,

(2)一个一个点往里面加,如果当前的点不在当前的圆内,

(3)在当前圆内的点找到另一个点,然后以这两个点做圆,

(4)再判断剩下的点,如果还有不在这个圆内的,以当前的这三个点做圆。

代码也巨好写无比,简直跟暴力一样,但是就是跑得过!!!

(唯一的难点就是推三点外接圆的式子,我这个傻逼推了一整个晚上)

代码:(以bzoj1336为例)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> #ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif #ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif #define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
inline double FastIn2()
{
R char ch = getc(); R double cnt = 0, ee = 1; R bool minus = 0, e = 0;
while (ch != '-' && (ch < '0' || ch > '9')) ch = getc();
if (ch == '-') minus = 1, ch = getc();
while (ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0' , ch = getc();
if (ch == '.') e = 1, ee *= 0.1, ch = getc();
while (ch >= '0' && ch <= '9' && e) cnt += (ch - '0') * ee, ee *= 0.1, ch = getc();
return minus ? -cnt : cnt;
}
#define maxn 1000010
struct Point
{
double x, y;
}p[maxn], o;
Point cir(Point a, Point b, Point c)
{
R Point res;
R double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1 * a1 + b1 * b1);
R double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2 * a2 + b2 * b2);
R double d = (a2 * b1 - a1 * b2) * 2;
res.x = a.x + (c2 * b1 - c1 * b2) / d;
res.y = a.y + (c1 * a2 - c2 * a1) / d;
return res;
}
#define dist(_a, _b) (sqrt((_a.x - _b.x) * (_a.x - _b.x) + (_a.y - _b.y) * (_a.y - _b.y) ) )
int main()
{
// setfile();
R int n = FastIn();
for (R int i = 1; i <= n; ++i)
p[i] = (Point) {FastIn2(), FastIn2()};
std::random_shuffle(p + 1, p + n + 1);
o = p[1];
R double r = 0;
for (R int i = 2; i <= n; ++i)
if (dist(p[i], o) > r)
{
o = p[i]; r = 0;
for (R int j = 1; j < i; ++j)
if (dist(p[j], o) > r)
{
o.x = (p[i].x + p[j].x) / 2;
o.y = (p[i].y + p[j].y) / 2;
r = dist(p[i], o);
for (R int k = 1; k < j; ++k)
if (dist(p[k], o) > r)
{
o = cir(p[i], p[j], p[k]);
r = dist(p[i], o);
}
}
}
printf("%.6f\n%.6f %.6f", r, o.x, o.y);
return 0;
}

【bzoj1336/1337/2823】最小圆覆盖的更多相关文章

  1. 2018.07.04 BZOJ1336&&1337: Balkan2002Alien最小圆覆盖

    1336: [Balkan2002]Alien最小圆覆盖 1337: 最小圆覆盖 Time Limit: 1 Sec Memory Limit: 162 MBSec Special Judge Des ...

  2. BZOJ1336 Balkan2002 Alien最小圆覆盖 【随机增量法】*

    BZOJ1336 Balkan2002 Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=100000, ...

  3. 【bzoj1336/1337/2823】[Balkan2002]Alien最小圆覆盖 随机增量法

    题目描述 给出N个点,让你画一个最小的包含所有点的圆. 输入 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000. ...

  4. Bzoj 1336&1337 Alien最小圆覆盖

    1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 Sec  Memory Limit: 162 MBSec  Special Judge Submit: 1473  ...

  5. bzoj1336: [Balkan2002]Alien最小圆覆盖

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1336 1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 ...

  6. 【BZOJ-1336&1337】Alie最小圆覆盖 最小圆覆盖(随机增量法)

    1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1573   ...

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

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

  8. 【BZOJ1336】[Balkan2002]Alien最小圆覆盖 随机增量法

    [BZOJ1336][Balkan2002]Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=10000 ...

  9. bzoj 2823: [AHOI2012]信号塔 最小圆覆盖

    题目大意: 给定n个点,求面积最小的园覆盖所有点.其中\(n \leq 10^6\) 题解: 恩... 刚拿到这道题的时候... 什么???最小圆覆盖不是\(O(n^3)\)的随机增量算法吗????? ...

随机推荐

  1. LSTM用于MNIST手写数字图片分类

    按照惯例,先放代码: import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #载入数据集 ...

  2. c++ k^1

    如果k是偶数,则使k=k+1:若k是奇数,则使k=k-1.

  3. fidder抓包工具使用方法,完整流程

    fidder抓包工具使用方法,完整流程 https://blog.csdn.net/lw545034502/article/details/82150779 版权声明:本文为博主原创文章,遵循 CC ...

  4. MyBatis框架 课程笔记

    MyBatis框架 课程笔记   第1章 MyBatis简介 1.1 MyBatis历史 1)MyBatis是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Softw ...

  5. Java编程思想学习录(连载之:内部类)

    内部类基本概念 可将一个类的定义置于另一个类定义的内部 内部类允许将逻辑相关的类组织在一起,并控制位于内部的类的可见性 甚至可将内部类定义于一个方法或者任意作用域内! 当然,内部类 ≠ 组合 内部类拥 ...

  6. ccs中a链接的四种状态

    什么是超链接? 超链接通俗地指从一个网页指向一个目标的连接关系,这个目标可以是另一个网页,也可以是相同网页上的不同位置,还可以是一个图片,一个电子邮件地址,一个文件,甚至是一个应用程序.而在一个网页中 ...

  7. P1969积木大赛

    这是2018与2013提高组的真题,可怕,,原题出了两年,是个纯模拟. 读完题后就想写一个朴素的模拟,先遍历层数,再把达到层数的宽度#存起来,再判断是否连续,如果不连续ans++,然后每一次循环都要初 ...

  8. 【JZOJ 3909】Idiot 的乘幂

    题面: 正文: 把题目中的方程组组合在一起就变成了: \(X^{a+c}\equiv b \cdot d (\mod p)\) 那这时,我们假定两个数\(x\)和\(y\),使得: \(ax + cy ...

  9. Linux安装Jenkins并部署springboot项目

    安装步骤: 1.跳转连接https://pkg.jenkins.io/redhat-stable/下载安装包 2.安装命令: sudo rpm -ih jenkins-2.73.2-1.1.noarc ...

  10. scala学习笔记(4)映射和元组

    1.构造映射 //构造这样的一个映射 val sources=Map(,,) //构造了一个不可变的Map[String,Int],值不能改变, //可变映射 val scores = new sca ...