随机增量法求最小覆盖圆,主要就是圆心坐标神烦,后来看到了ACdreamer的一个简洁版本,虽然还没明白是为什么但是比窝那个短多了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iomanip>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
#define N 1000005
#define eps 1e-8
struct P
{
double x,y;
}d[N];
int n;
double dis(P a,P b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
P get(P A,P B,P C)
{
P t;
double a1=B.x-A.x,b1=B.y-A.y,c1=(a1*a1+b1*b1)/2;
double a2=C.x-A.x,b2=C.y-A.y,c2=(a2*a2+b2*b2)/2;
double d=a1*b2-a2*b1;
t.x=A.x+(c1*b2-c2*b1)/d;
t.y=A.y+(a1*c2-a2*c1)/d;
return t;
}
P get(P a,P b)
{
return (P){(a.x+b.x)/2,(a.y+b.y)/2};
}
int main()
{
scanf("%d",&n);
fo(i,1,n) scanf("%lf%lf",&d[i].x,&d[i].y);
P t=d[1];double r=0.0;
fo(i,1,n)
{
if (dis(d[i],t)<=r+eps) continue;
t=d[i];r=0;
fo(j,1,i-1)
{
if (dis(d[j],t)<=r+eps) continue;
t=get(d[i],d[j]);r=dis(d[j],t);
fo(k,1,j-1)
{
if (dis(d[k],t)<=r+eps) continue;
t=get(d[i],d[j],d[k]);r=dis(d[k],t);
}
}
}
printf("%.2lf %.2lf %.2lf\n",t.x,t.y,r);
return 0;
}