题意:
就是给你n个点,问你在那个点是到所有点距离的最大值最小。
思考:
一看就是几何题,但是怎么做呢,好像有啥板子才行。然后答案让你输出小数点后几位的,一般答案都可以不太精确即可。所以如果能退火就退火,这个也就是先选一个点,然后随机下一个点,如果当前的最小值更优,那么就过去。跑10次退火取答案最好的时候即可。
代码:
struct point{
db x,y,z;
}node[N];
int T,n,m,k;
int va[N];
db anw = inf;
db dis(db x,db y,db z)
{
db sum = 0;
for(int i=1;i<=n;i++)
{
db res = 0;
res += (x-node[i].x)*(x-node[i].x);
res += (y-node[i].y)*(y-node[i].y);
res += (z-node[i].z)*(z-node[i].z);
sum = max(sum,sqrt(res));
}
return sum;
}
void SA()
{
db te = 3000,delt = 0.99,eps = 1e-15;
db x = 0,y = 0,z = 0,ans = inf;
while(te>eps)
{
db xx = x+(rand()*2-RAND_MAX)*te;
db yy = y+(rand()*2-RAND_MAX)*te;
db zz = z+(rand()*2-RAND_MAX)*te;
db ans_t = dis(xx,yy,zz);
db pro = exp((ans-ans_t)/te)*RAND_MAX;
if(ans>ans_t||pro>rand())
{
ans = ans_t;
x = xx,y = yy,z = zz;
}
te *= delt;
}
anw = min(anw,ans);
}
signed main()
{
IOS;
srand(time(NULL));
cin>>n;
for(int i=1;i<=n;i++)
{
db a,b,c;
cin>>a>>b>>c;
node[i] = {a,b,c};
}
for(int i=1;i<=10;i++) SA();
printf("%.8lf",anw);
return 0;
}
总结:
多多积累经验。