Problem
- 给定三维空间的一些点,求出一个点使得该点到其它点的最大距离最小。
场上读错题了 。
Solution
- 设最大距离为G(x,y,z)。在x,y确定的情况下G是个关于z单峰函数,开口向上,为此可以依次确定答案的三个坐标:对于ansx,三分x,求出每个待判断的x(三等分点)下的最小值(三分y然后三分z),求ansy与ansz同理。
Code
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int mx=1e4;
const double eps=1e-8;
int n;
double ansx,ansy,ansz;
struct node{
double x,y,z;
}p[105];
double fz(double x,double y,double z)
{
double dis=0;
for(int i=1;i<=n;i++)
dis=max(dis,sqrt((x-p[i].x)*(x-p[i].x)+(y-p[i].y)*(y-p[i].y)+(z-p[i].z)*(z-p[i].z)));
return dis;
}
double fy(double x,double y)
{
double l=-mx,r=mx,ml,mr;
while(r-l>eps)
{
ml=(l*2+r)/3;mr=(r*2+l)/3;
if(fz(x,y,ml)<fz(x,y,mr))
r=mr;
else
l=ml;
}
return fz(x,y,l);
}
double fx(double x)
{
double l=-mx,r=mx,ml,mr;
while(r-l>eps)
{
ml=(l*2+r)/3;mr=(r*2+l)/3;
if(fy(x,ml)<fy(x,mr))
r=mr;
else
l=ml;
}
return fy(x,l);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>p[i].x>>p[i].y>>p[i].z;
double l=-mx,r=mx,ml,mr;
while(r-l>eps)
{
ml=(l*2+r)/3;mr=(r*2+l)/3;
if(fx(ml)<fx(mr))
r=mr;
else
l=ml;
}
ansx=l;l=-mx;r=mx;
while(r-l>eps)
{
ml=(l*2+r)/3;mr=(r*2+l)/3;
if(fy(ansx,ml)<fy(ansx,mr))
r=mr;
else
l=ml;
}
ansy=l;l=-mx;r=mx;
while(r-l>eps)
{
ml=(l*2+r)/3;mr=(r*2+l)/3;
if(fz(ansx,ansy,ml)<fz(ansx,ansy,mr))
r=mr;
else
l=ml;
}
ansz=l;
printf("%.7lf %.7lf %.7lf",ansx,ansy,ansz);
return 0;
}