参考的楼上博主的思路,我重新理顺了一下思路,用我的话来表达,可能比较好理解 ,楼上博主的表述比较厉害(狗头保命
思路:假设我们在前 i 个点已经确定了一个圆,然后第 i+1个点在圆外面了,那么我们可以知道这个点和前i个点的距离比较远,则我们选择这个点作为圆的边界,然后在前i个点中再选一个点(与其距离最远,假设是第j个点),j和第i+1个点作为圆的直径(这样可以保证第j到第i+1个点全在则个圆内,画图易得),在前j-1个点中遍历,若还有点在圆外,则,和第j,i+1点三点做出一个圆,则这样所有点都在圆内了;
#include <iostream>
#include <cmath>
#include <cstdio>
#include <stdlib.h>
#include <ctime>
#include <algorithm>
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
using namespace std;
const double pi=acos(-1.0);
double r=0;
struct node
{
double x,y;
}e[105],O;
inline double getdis(node a,node b)
{
double x=a.x-b.x,y=a.y-b.y;
return sqrt(x*x+y*y);
}
inline double workO(node p1,node p2,node p3)
{
double x1=2*(p2.x-p1.x),y1=2*(p2.y-p1.y);
double c1=p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y;
double x2=2*(p3.x-p1.x),y2=2*(p3.y-p1.y);
double c2=p3.x*p3.x+p3.y*p3.y-p1.x*p1.x-p1.y*p1.y;
O.x=(y1*c2-y2*c1)/(y1*x2-y2*x1);
O.y=(x2*c1-x1*c2)/(y1*x2-y2*x1);
return getdis(O,p1);
}
int main()
{
for(;;)
{
int n;cin>>n;
if(n==0) break;
for(int i=1;i<=n;i++) scanf("%lf%lf",&e[i].x,&e[i].y);
random_shuffle(e+1,e+n+1);
O=e[1],r=0;
for(int i=2;i<=n;i++)
{
if(getdis(O,e[i])>r)
{
O=e[i],r=0;
for(int j=1;j<=i-1;j++)
{
if(getdis(O,e[j])>r)
{
O.x=(e[i].x+e[j].x)/2;
O.y=(e[i].y+e[j].y)/2;
r=getdis(O,e[i]);
for(int k=1;k<=j-1;k++)
{
if(getdis(e[k],O)>r)
{
r=workO(e[i],e[j],e[k]);
}
}
}
}
}
}
printf("%.2lf %.2lf %.2lf\n",O.x,O.y,r);
}
return 0;
}