题意:题目给n个三维点坐标(x,y,z),现在希望存在一个点,使得这个点到所有n个点的最大距离最小,然后求该最大距离。即用一个半径最小的球把所有点都放进去,求该球半径
思路:看了半天最小圆,然后发现这个直接可以三分球心坐标
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 150;
const ll mod = (ll)1e9 +7;
typedef struct node
{
double p[3];
}node;
int n;
node po[maxn];
double dis(node x, node y)
{
return sqrt((x.p[0]-y.p[0])*(x.p[0]-y.p[0])+
(x.p[1]-y.p[1])*(x.p[1]-y.p[1])+(x.p[2]-y.p[2])*(x.p[2]-y.p[2]));
}
double cal(node a)
{
double res = 0;
for(int i=0;i<n;i++)
{
res = max(res,dis(a,po[i]));
}
return res;
}
node sol(int dir, node now)
{
if(dir>=3)return now;
double l = -100000.0, r = 100000.0, kl, kr;
node ra, rb, ans, tl, tr;
ans = tl = tr = now;
while(r-l>1e-9)
{
kl = (2*l+r)/3;
kr = (l+2*r)/3;
tl.p[dir] = kl, tr.p[dir] = kr;
ra = sol(dir+1,tl);
rb = sol(dir+1,tr);
if(cal(ra)>cal(rb))
{
l = kl;
ans = rb;
}
else
{
r = kr;
ans = ra;
}
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lf%lf%lf",&po[i].p[0],&po[i].p[1],&po[i].p[2]);
}
node ans;
double k = cal(sol(0,ans));
printf("%.9lf\n",k);
}