【bzoj1336/1337/2823】最小圆覆盖
题目描述:
给出平面上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】最小圆覆盖的更多相关文章
- 2018.07.04 BZOJ1336&&1337: Balkan2002Alien最小圆覆盖
		
1336: [Balkan2002]Alien最小圆覆盖 1337: 最小圆覆盖 Time Limit: 1 Sec Memory Limit: 162 MBSec Special Judge Des ...
 - BZOJ1336 Balkan2002 Alien最小圆覆盖 【随机增量法】*
		
BZOJ1336 Balkan2002 Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=100000, ...
 - 【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 ...
 - bzoj1336: [Balkan2002]Alien最小圆覆盖
		
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1336 1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 ...
 - 【BZOJ-1336&1337】Alie最小圆覆盖         最小圆覆盖(随机增量法)
		
1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1573 ...
 - 2018.07.04 BZOJ 2823: AHOI2012信号塔(最小圆覆盖)
		
2823: [AHOI2012]信号塔 Time Limit: 10 Sec Memory Limit: 128 MB Description 在野外训练中,为了确保每位参加集训的成员安全,实时的掌握 ...
 - 【BZOJ1336】[Balkan2002]Alien最小圆覆盖 随机增量法
		
[BZOJ1336][Balkan2002]Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=10000 ...
 - bzoj 2823: [AHOI2012]信号塔 最小圆覆盖
		
题目大意: 给定n个点,求面积最小的园覆盖所有点.其中\(n \leq 10^6\) 题解: 恩... 刚拿到这道题的时候... 什么???最小圆覆盖不是\(O(n^3)\)的随机增量算法吗????? ...
 
随机推荐
- C/C++ 内存模型
			
C分为四个区:堆,栈,静态全局变量区,常量区 C++内存分为5个区域(堆栈全常代 ): 堆 heap : 由new分配的内存块,其释放编译器不去管,由我们程序自己控制(一个new对应一个delete) ...
 - ^A  '\001' 分隔符
			
^A 分隔符符号\001,使用组合按键“ctrl+V+A”获得
 - 洛谷 - P1462 - 通往奥格瑞玛的道路 - 二分 - Dijkstra
			
https://www.luogu.org/problem/P1462 感觉,要二分最大收费权的城市,把小于等于它的全部插进去,Dijkstra一下求出最小的血量.这样感觉太暴力了. 考虑只有1000 ...
 - Nginx设置上传文件大小限制
			
就是nginx对上传的图片大小有了限制嘛,所以更改nginx的配置文件就好了 client_max_body_size 1000m; 参考:https://blog.csdn.net/TitanSee ...
 - Linux Qt cannot find -lGL错误完美解决方案(亲测有效)
			
http://c.biancheng.net/view/3901.html 对于很多 Linux 发行版本,Qt 安装完成后如果直接编译或者运行项目,会出现“cannot find -lGL”错误,如 ...
 - 洛谷 P1896 [SCOI2005]互不侵犯 (状态压缩DP)
			
题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 注:数据有加强(2018/4/25) ...
 - [易学易懂系列|golang语言|零基础|快速入门|(三)]
			
接下来,我们主要讲讲package. 先列举下go的package的一些核心特性: 1.go的package不局限于一个文件,组成一个package的多个文件,编译后实际上和一个文件类似,组成包的不同 ...
 - Saving James Bond - Easy Version
			
题目来源: 浙江大学在慕课网上开设的<数据结构>课,陈越老师.何钦铭老师主讲,课后作业的一道题. 题目描述: 题目思路: 这道题目本质上讲就是列出图的连通集,但是这个连通集的起点是有约束的 ...
 - python3:类和实例
			
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可 ...
 - 使用pycharm创建git项目的过程
			
首先建立远程仓库,然后将远程仓库克隆到本地 然后在pycharm中以该目录创建项目(如果遇到说目录非空,不用管它,Location直接粘贴古来,不然找不到路径) 如果构建好项目说无效的SDK,那么选择 ...