BZOJ 1337: 最小圆覆盖1336: [Balkan2002]Alien最小圆覆盖(随机增量法)
今天才知道有一种东西叫随机增量法就来学了= =
挺神奇的= =
A.令ci为包括前i个点的最小圆,若第i+1个点无法被ci覆盖,则第i+1个点一定在ci+1上
B.令ci为包括前i个点的最小圆且p在边上,若第i+1个点无法被ci覆盖,则第i+1个点与点p一定在ci+1上
C.令ci为包括前i个点的最小圆且p,q在边上,若第i+1个点无法被ci覆盖,则第i+1个点与点p,q一定在ci+1上
这样就确定一个圆了
这样看上去是O(n^3)的,但是注意这个名字= =随机,说明我们能通过随机使其降到O(n)
首先C显然是线性
那么B-》c呢?对于一个点pi,在院内的概率是(i-1)/i在圆外的概率是1/i(因为这些点是随机的= =) 所以加入的复杂度为(i-1)/i*O(1)+1/i*O(i);
A-》B同理,因此该算法的时间复杂度为线性的
随机化多么神奇啊= =
c++可以直接random_shuffle(STL多么神奇!!!)来随机化数组
CODE:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define maxn 100100
typedef pair<double,double> ii;
ii a[maxn],cir;
double r;
double dis(ii x,ii y) {
return sqrt(sqr(x.fi-y.fi)+sqr(x.se-y.se));
}
ii getcir(ii x,ii y,ii z){
double a=sqr(x.fi)-sqr(y.fi)+sqr(x.se)-sqr(y.se),
b=sqr(x.fi)-sqr(z.fi)+sqr(x.se)-sqr(z.se),
c=2*(x.se-z.se)*(x.fi-y.fi)-2*(x.se-y.se)*(x.fi-z.fi);
return ii((a*(x.se-z.se)-b*(x.se-y.se))/c,
(a*(x.fi-z.fi)-b*(x.fi-y.fi))/(-c));
}
#define exp 1e-10
int cmp(double x) {
if (x<-exp) return -1;
if (x>exp) return 1;
return 0;
}
int n;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].fi,&a[i].se);
random_shuffle(a+1,a+1+n);
cir=a[1],r=0;
for (int i=1;i<=n;i++) {
if (cmp(dis(cir,a[i])-r)<=0) continue;
cir=a[i],r=0;
for (int j=1;j<i;j++) {
if (cmp(dis(cir,a[j])-r)<=0) continue;
cir.fi=(a[i].fi+a[j].fi)/2,cir.se=(a[i].se+a[j].se)/2;
r=dis(cir,a[j]);
for (int k=1;k<j;k++) {
if (cmp(dis(cir,a[k])-r)<=0) continue;
cir=getcir(a[i],a[j],a[k]);
r=dis(cir,a[i]);
}
}
}
printf("%lf\n%lf %lf\n",r,cir.fi,cir.se);
return 0;
}
BZOJ 1337: 最小圆覆盖1336: [Balkan2002]Alien最小圆覆盖(随机增量法)的更多相关文章
- [BZOJ 1336] [Balkan2002] Alien最小圆覆盖 【随机增量法】
题目链接:BZOJ - 1336 题目分析 最小圆覆盖有一个算法叫做随机增量法,看起来复杂度像是 O(n^3) ,但是可以证明其实平均是 O(n) 的,至于为什么我不知道= = 为什么是随机呢?因为算 ...
- 【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不在圆里面, ...
- 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 ...
- 【bzoj1336/1337/2823】[Balkan2002]Alien最小圆覆盖 随机增量法
题目描述 给出N个点,让你画一个最小的包含所有点的圆. 输入 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000. ...
- BZOJ1336 Balkan2002 Alien最小圆覆盖 【随机增量法】*
BZOJ1336 Balkan2002 Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=100000, ...
- 【BZOJ1336】[Balkan2002]Alien最小圆覆盖 随机增量法
[BZOJ1336][Balkan2002]Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=10000 ...
- BZOJ.2823.[AHOI2012]信号塔(最小圆覆盖 随机增量法)
BZOJ 洛谷 一个经典的随机增量法,具体可以看这里,只记一下大体流程. 一个定理:如果一个点\(p\)不在点集\(S\)的最小覆盖圆内,那么它一定在\(S\bigcup p\)的最小覆盖圆上. 所以 ...
随机推荐
- Unable to list the users SQLSTATE =S0002
powerdesinger mysql 反向工程时报错 解决方案: database ->change the Target DNMS 修改DBMS为mysql 的对应版本 修改后,点击确定即可 ...
- 为什么32位操作系统最大支持4GB内存
因为32位操作系统的地址空间为32位,地址总数为2^32,每个地址对应1Byte内存空间,这样,32位操作系统管理的最大内存空间限制为2^32Byte=4*1024*1024*1024Byte,即4G ...
- beforeunload
<!DOCTYPE html> <html> <head> <title>BeforeUnload Event Example</title> ...
- hdu 1005解题报告
这道题目n的取值范围很大,1 <= n <= 100,000,000.因此肯定是需要优化才能AC. 首先我考虑到时是有没有通项公式,研究了一下,没发现什么东西,突然看到两个1时就想到会不会 ...
- Selenium2(java)定位页面元素 二
辅助工具: chrome浏览器,F12打开控制台; Firefox浏览器,F12打开控制台; 或者选中要定位的元素右键 安装firefox扩展firebug和firepath; 安装之后F12可调用f ...
- Java经典案例之-判断质数(素数)
/** * 描述:任意输入两个数n,m(n<m)判断n-m之间有多少个素数,并输出所有素数. * 分析:素数即质数,除1和本身之外,不能被其他自然数整除的数. * 判断素数的方法为:用一个数分别 ...
- 冒泡排序法-java案例详解
/** * 功能:冒泡排序法 * 思想:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的排序码, * ,若发现逆序这交换,使得排序码较小的元素逐渐从后部移向前部(从下标较大的单元移 ...
- AngularJs ui-router 路由的介绍
AngularJs ui-router 路由介绍 野兽之前有写过一篇关于Angular自带的路由:ngRoute.今天来说说Angular的第三方路由:ui-router.那么有人就会问:为什么Ang ...
- php判断IE浏览器
<?php/** * 检测用户当前浏览器 * @return boolean 是否ie浏览器 */ function chk_ie_browser() { $userbrowser = $_SE ...
- 如何去掉Atom的右键菜单?
Win+R -- regedit -- Ctrl+F -- 搜索"Atom"(或者直接"Open with Atom") -- 找到有个值为Open with ...