#include<bits/stdc++.h>
using namespace std;
/*模拟退火思路
在退火时找到每个点的平均距离
然后近的就推
远的就拉
变化量再*当时的温度
完成模拟退火,只用退一次
*/
int n;
struct point{
double num[16];
};
point p[19],ans,delta;
//p存点,ans存答案,delta存转移
double dist(point a,point b){
//求两点间的距离
double ret=0;
for(int i=1;i<=n;i++){
ret+=(a.num[i]-b.num[i])*(a.num[i]-b.num[i]);
}
return sqrt(ret);
}
double dis[12];
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(f=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
int main(){
cin>>n;
int xt=0;
for(int i=1;i<=n+1;i++){
for(int j=1;j<=n;j++){
cin>>p[i].num[j];
ans.num[j]+=p[i].num[j];
}
}
for(int i=1;i<=n;i++)
ans.num[i]/=(n+1);
for(double T=1000;T>=0.0001;T*=0.9999){
//模拟退火
double ave=0;
for(int i=1;i<=n+1;i++){
dis[i]=dist(ans,p[i]);
ave+=dis[i];
}
ave/=n+1;//当前平均距离
for(int i=1;i<=n;i++)
delta.num[i]=0;//初始
for(int i=1;i<=n+1;i++)
for(int j=1;j<=n;j++){
delta.num[j]+=(dis[i]-ave)*(p[i].num[j]-ans.num[j])/ave;
}
for(int i=1;i<=n;i++){
ans.num[i]+=delta.num[i]*T;
//修改答案
}
}
for(int i=1;i<=n;i++)
printf("%0.3f ",ans.num[i]);
return 0;
}
我改了好多次T和down都没过