BZOJ1337: 最小圆覆盖

题目:求n个点的最小圆覆盖。

题解:最小圆覆盖,上模板。复杂度证明可以戳:这里

代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 1000000+5
14 #define maxm 200000+5
15 #define eps 1e-6
16 #define ll long long
17 #define ull unsigned long long
18 #define pa pair<int,int>
19 #define for0(i,n) for(int i=0;i<=(n);i++)
20 #define for1(i,n) for(int i=1;i<=(n);i++)
21 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
22 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
23 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
24 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
25 #define mod 1000000007
26 #define lch k<<1,l,mid
27 #define rch k<<1|1,mid+1,r
28 #define sqr(x) (x)*(x)
29 #define db double
30 using namespace std;
31 inline int read()
32 {
33     int x=0,f=1;char ch=getchar();
34     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
35     while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}
36     return x*f;
37 }
38 struct point
39 {
40     db x,y;
41     point operator +(point b){return (point){x+b.x,y+b.y};}
42     point operator /(db b){return (point){x/b,y/b};}
43 }a[maxn];
44 int n;
45 db ans;
46 inline db dist(point a,point b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
47 inline point calc(db a,db b,db c,db d,db e,db f)
48 {
49   return (point){(c*e-f*b)/(a*e-d*b),(a*f-c*d)/(a*e-d*b)};
50 }
51 inline point get(point a,point b,point c)
52 {
53    return calc(b.x-a.x,b.y-a.y,(sqr(b.x)+sqr(b.y)-sqr(a.x)-sqr(a.y))/2.0,
54         c.x-b.x,c.y-b.y,(sqr(c.x)+sqr(c.y)-sqr(b.x)-sqr(b.y))/2.0);
55 }
56 int main()
57 {
58    freopen("input.txt","r",stdin);
59    freopen("output.txt","w",stdout);
60    n=read();
61    for1(i,n)scanf("%lf%lf",&a[i].x,&a[i].y);
62    for1(i,n)swap(a[rand()%n+1],a[rand()%n+1]);
63    ans=0;
64    for1(i,n)if(dist(a[i],a[0])>ans+eps)
65    {
66         a[0]=a[i];ans=0;
67         for1(j,i-1)if(dist(a[j],a[0])>ans+eps)
68         {
69             a[0]=(a[i]+a[j])/2;ans=dist(a[0],a[i]);
70             for1(k,j-1)if(dist(a[k],a[0])>ans+eps)
71             {
72                 a[0]=get(a[i],a[j],a[k]);ans=dist(a[0],a[i]);
73             }
74         }
75    }
76    printf("%.2f %.2f %.2f\n",a[0].x,a[0].y,ans);
77    return 0;
78 }

我不会说告诉你这题是三倍经验的

时间: 2024-10-01 07:56:24

BZOJ1337: 最小圆覆盖的相关文章

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

1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1573  Solved: 697[Submit][Status][Discuss] Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000.0) Outpu

最小圆覆盖模板

//最小圆覆盖 //输入: 从下标0开始的点集_ps和大小_n //输出: 覆盖所有点的最小圆 //复杂度: O(n) //注意: 会对_ps进行随机处理操作,将会改变点集的内部顺序 Circle MinCoverCir(Point _ps[],int _n) { //随机处理,但是会改变传入的点集. random_shuffle(_ps, _ps+_n);//复杂度O(_n) Circle rec; rec.r = 0; rec.c = _ps[0]; for(int i=1;i<_n;i++

ZOJ 1450 Minimal Circle 最小圆覆盖

套了个模板直接上,貌似没有随机化序列 QAQ //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <cstring> #include <cmath> #include <stack> #include <queue> #include <

最小圆覆盖 hdu 3007

今天学习了一下最小圆覆盖, 看了一下午都没看懂, 晚上慢慢的摸索这代码,接合着别人的讲解, 画着图跟着代码一步一步的走着,竟然有些理解了. 最小圆覆盖: 给定n个点, 求出半径最小的圆可以把这些点全部包围, 可以在圆的边界上 下面是我的个人理解. 如果不对, 还请路过大牛指出 先找一个点, 让圆心等于这个点的坐标, 半径等于0, 显然这个对的, 接着找下一个点, 如果只有两个点的话, 那么最小的圆一定是以他们为直径做圆, 接着找第三个点, 如果第三个点在园内或者在边界上, 那么不用更新当前的最小

BZOJ 2823 AHOI 2012 信号塔 凸包+最小圆覆盖

题目大意:给出平面上n个点,求最小圆覆盖. 思路:圆覆盖问题只与所有点中凸包上的点有关,因此先求一下凸包,然后数据范围骤减.大概是只剩下logn左右个点.这样就可以随便浪了. 先找所有三个点组成的圆,然后找两个点为直径所组成的圆. 还有就是三角形的外心公式,简直不是人推的,然后我就机制的百度了,结果如下: 不要模拟退火... 样例很坑,当你算出2.49 2.86的时候,不要认为你被卡精了,其实是你写挂了... CODE: #include <cmath> #include <cstdio

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

题目描述 给出N个点,让你画一个最小的包含所有点的圆. 输入 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000.0) 输出 输出圆的半径,及圆心的坐标 样例输入 6 8.0 9.0 4.0 7.5 1.0 2.0 5.1 8.7 9.0 2.0 4.5 1.0 样例输出 5.00 5.00 5.00 题解 随机增量法求最小圆覆盖裸题 求法:设初始圆为某空圆,先枚举第一个点,如果不在当前圆内,则令当前圆为这一个点的最小圆

最小圆覆盖

本来不想学的-于是今天就碰到一道大裸题- 例题:bzoj2823 求最小圆覆盖n个点. 伪代码如下: 把所有点随机化,设为(x[1],y[1])...(x[n],y[n]) 开始把圆心设为x[1],半径设为0 for i=2 to n 如果i号点在当前圆内则跳过 //那么i号点就在圆周上 把1号点和i号点作为直径作一个圆 for j=1 to i-1 如果j号点在当前圆内则跳过 考虑以j号点和i号点作为直径作一个圆 for k=1 to j-1 如果k号点在当前圆内则跳过 以i,j,k三点组成的

HDOJ 2215 Maple trees 最小圆覆盖

增量法最小圆覆盖.... Maple trees Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1646    Accepted Submission(s): 510 Problem Description There are a lot of trees in HDU. Kiki want to surround all the t

【bzoj2280】[Poi2011]Plot 二分+倍增+二分+最小圆覆盖

题目描述 给出一系列点p_1, p_2, ... , p_n,将其分成不多余m个连续的段,第i段内求一个点q_i,使得q_i到这段内点的距离的最大值的最大值最小 输入 第一行,n m下面n行,每行两个整数,表示p_i的x y坐标1<=m<=n<=100000坐标范围[-1000000,1000000] 0<p,q,r<=150,输入中至少包含一个’N’ 输出 第一行,q_i到这段内点的距离的最大值的最大值的最小值第二行,分成的段数k下面k行,每行两个实数,表示q_k的x y坐