P1742 最小圆覆盖

P1742 最小圆覆盖

最小圆覆盖板子。

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long double ldb;
struct Poi{
    Poi(){} ldb x,y;
    Poi(ldb A,ldb B):x(A),y(B){}
    Poi operator + (Poi G){return Poi(x+G.x,y+G.y);}
    Poi operator - (Poi G){return Poi(x-G.x,y-G.y);}
    Poi operator * (ldb G){return Poi(x*G,y*G);}
    ldb operator * (Poi G){return x*G.y-y*G.x;}
}a[100005];
Poi ro_90(Poi A){return Poi(A.y,-A.x);}
ldb len2(Poi A){return A.x*A.x+A.y*A.y;}
struct Line{
    Line(){} Poi p,v;
    Line(Poi A,Poi B):p(A),v(B){}
};
struct Ring{
    Ring(){} Poi o; ldb r;
    Ring(Poi A,ldb B):o(A),r(B){}
    bool out(Poi G){return r*r<len2(o-G);}
}C=Ring(Poi(0,0),0);
Poi Inter(Line A,Line B){
    Poi u=A.p-B.p,v=A.v,w=B.v;
    ldb t=(w*u)/(v*w);
    return A.p+A.v*t;
}
Ring Circle(Poi A,Poi B,Poi C){//求A,B,C外接圆
    Line p1=Line((A+B)*0.5,ro_90(B-A));
    Line p2=Line((B+C)*0.5,ro_90(B-C));
    Poi O=Inter(p1,p2);
    return Ring(O,sqrt(len2(O-A)));
}
int n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%Lf%Lf",&a[i].x,&a[i].y);
    random_shuffle(a+1,a+n+1);
    for(int i=1;i<=n;++i) if(C.out(a[i])){
        C=Ring(a[i],0);
        for(int j=1;j<i;++j) if(C.out(a[j])){
            C=Ring((a[i]+a[j])*0.5,sqrt(len2(a[i]-a[j]))*0.5);
            for(int k=1;k<j;++k) if(C.out(a[k])){
                C=Circle(a[i],a[j],a[k]);
            }
        }
    }printf("%.10Lf\n%.10Lf %.10Lf",C.r,C.o.x,C.o.y);
    return 0;
}

 

posted @ 2019-08-01 21:54  kafuuchino  阅读(121)  评论(0编辑  收藏  举报