首页 > 其他 > 详细

P1742 最小圆覆盖

时间:2019-08-01 22:55:33      阅读:105      评论:0      收藏:0      [点我收藏+]

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;
}

 

P1742 最小圆覆盖

原文:https://www.cnblogs.com/kafuuchino/p/11285631.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!