[Balkan2002]Alien最小圆覆盖

Posted lcxer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Balkan2002]Alien最小圆覆盖相关的知识,希望对你有一定的参考价值。

传送门

期望(O(n))的神奇算法
代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
void read(int &x){
    char ch; bool ok;
    for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=1e5+1;
double eps=1e-6;
int n;
struct oo{double x,y;}a[maxn];
struct circle{double x,y,r;}c;
double dis(double x,double y,oo a){return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));}
circle make_2(oo a,oo b){return (circle){(a.x+b.x)/2.0,(a.y+b.y)/2.0,dis((a.x+b.x)/2.0,(a.y+b.y)/2.0,b)};}
circle make_3(oo x1,oo x2,oo x3)
{
    double a=x1.x-x2.x,b=x1.y-x2.y,c=x1.x-x3.x,d=x1.y-x3.y,
    e=((x1.x*x1.x-x2.x*x2.x)-(x2.y*x2.y-x1.y*x1.y))/2.0,
    f=((x1.x*x1.x-x3.x*x3.x)-(x3.y*x3.y-x1.y*x1.y))/2.0,x0,y0;
    x0=(d*e-b*f)/(a*d-b*c),y0=(c*e-a*f)/(b*c-a*d);
    return (circle){x0,y0,dis(x0,y0,x1)};
}
int main()
{
    srand(1e9+7);
    read(n);
    for(rg int i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);
    random_shuffle(a+1,a+n+1);
    c=make_2(a[1],a[2]);
    for(rg int i=3;i<=n;i++)
        if(dis(c.x,c.y,a[i])-c.r>eps)
        {
            c=make_2(a[1],a[i]);
            for(rg int j=1;j<i;j++)
                if(dis(c.x,c.y,a[j])-c.r>eps)
                {
                    c=make_2(a[i],a[j]);
                    for(rg int k=1;k<j;k++)
                        if(dis(c.x,c.y,a[k])-c.r>eps)
                            c=make_3(a[i],a[j],a[k]);
                }
        }
    printf("%lf
%lf %lf
",c.r,c.x,c.y);
}

或者也可以选择put("nan");

以上是关于[Balkan2002]Alien最小圆覆盖的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj1336] [Balkan2002]Alien最小圆覆盖

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

bzoj2823: [AHOI2012]信号塔&&1336: [Balkan2002]Alien最小圆覆盖&&1337: 最小圆覆盖

Java案例:最小覆盖圆问题

Java案例:最小覆盖圆问题

Java案例:最小覆盖圆问题