经典的最小圆覆盖问题,推公式略恶心。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define md
#define ll long long
#define inf (int) 1e9
#define eps 1e-6
#define N 500010
using namespace std;
struct point { double x,y;} p[N];
int fcmp(double a,double b)
{
if (a-b>eps) return 1;
if (a-b<-eps) return -1;
return 0;
}
point operator + (point a,point b) { return (point) {a.x+b.x,a.y+b.y};}
point operator - (point a,point b) { return (point){a.x-b.x,a.y-b.y}; }
point operator / (point a,double b) { return (point){a.x/b,a.y/b};}
double operator * (point a,point b) { return a.x*b.y-a.y*b.x;}
double dot(point a,point b) { return a.x*b.x+a.y*b.y;}
double len (point a) { return sqrt(a.x*a.x+a.y*a.y);}
point cal(point p1,point p2,point p3)
{
point p;
if (fcmp((p2-p1)*(p3-p1),0)==0)
{
if (dot(p2-p1,p3-p1)<0) p=(p2+p3)/2;
else if (dot(p1-p2,p3-p2)<0) p=(p1+p3)/2;
else p=(p1+p2)/2;
return p;
}
double a1,a2,b1,b2,c1,c2;
a1=-2*p1.x+2*p2.x; b1=p1.x*p1.x-p2.x*p2.x+p1.y*p1.y-p2.y*p2.y; c1=2*p1.y-2*p2.y;
a2=-2*p2.x+2*p3.x; b2=p2.x*p2.x-p3.x*p3.x+p2.y*p2.y-p3.y*p3.y; c2=2*p2.y-2*p3.y;
//printf("%.2lf %.2lf %.2lf %.2lf %.2lf %.2lf\n",a1,b1,c1,a2,b2,c2);
p.x=(c1*b2-b1*c2)/(a1*c2-a2*c1);
p.y=(a1*p.x+b1)/c1;
//printf("now: %.2lf %.2lf %.2lf\n",len(p1-p),len(p2-p),len(p3-p));
return p;
}
int main()
{
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
for (int i=1;i<=n;i++) swap(p[i],p[rand()%n+1]);
if (n==1) { printf("%.2lf %.2lf 0.00",p[1].x,p[1].y); return 0;}
if (n==2) { point ans=(p[1]+p[2])/2; printf("%.2lf %.2lf %.2lf\n",ans.x,ans.y,len(ans-p[1])); return 0;}
point o=p[1]; double r=0; //printf("ans: %.2lf %.2lf %.2lf\n",o.x,o.y,r);
for (int i=2;i<=n;i++)
{
if (fcmp(len(p[i]-o),r)<=0) continue;
o=(p[1]+p[i])/2; r=len(p[1]-o);
for (int j=2;j<i;j++)
{
if (fcmp(len(p[j]-o),r)<=0) continue;
o=(p[i]+p[j])/2; r=len(p[i]-o); //printf("%d %d %d\n",1,i,j);
for (int k=1;k<j;k++)
{
if (fcmp(len(p[k]-o),r)<=0) continue;
o=cal(p[i],p[j],p[k]); r=len(p[i]-o);
//printf("%d %d %d\n",i,j,k);
}
}
}
printf("%.2lf %.2lf %.2lf\n",o.x,o.y,r);
return 0;
}