题目链接:https://nanti.jisuanke.com/t/A2141
题目大意:三维空间有n个点,找到另外一个点,离所有点的最大距离最小。求这个距离。和之前的模拟退火的坐标构造方法不同。
初始化 x, y, z 坐标的平均值,然后每次向最远的点移动一定的距离
#include <bits/stdc++.h>
using namespace std;
double x[105], y[105], z[105];
int n;
double ansx=0, ansy=0, ansz=0;
double ans=1e18, t, sx=0, sy=0, sz=0;
const double p=0.98;
double dit(double xx, double yy, double zz, int i){
return sqrt((x[i]-xx)*(x[i]-xx)+(y[i]-yy)*(y[i]-yy)+(z[i]-zz)*(z[i]-zz));
}
void sim(){
t=1000;
while(t>1e-13){
int px=-1;//距离当前最远点
double s=-1;//最远距离
for(int i=1; i<=n; i++){
if(dit(ansx, ansy, ansz, i)>s){
s=dit(ansx, ansy, ansz, i);
px=i;
}
}
ans=min(ans, s);
ansx=ansx+(x[px]-ansx)*t/1000;//一定概率运动
ansy=ansy+(y[px]-ansy)*t/1000;
ansz=ansz+(z[px]-ansz)*t/1000;
t*=p;
}
}
void slove(){
ansx=sx/n, ansy=sy/n, ansz=sz/n;//平均值附件最容易找到最优值
sim();
sim();
sim();
}
int main()
{
srand(rand());
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%lf%lf%lf", &x[i], &y[i], &z[i]);
sx+=x[i], sy+=y[i], sz+=z[i];
}
slove();
printf("%.7f\n", ans);
return 0;
}
/* 3 0 0 0 3 0 0 0 4 0 */