球形空间产生器 [高斯消元/模拟退火]
有一个球形空间产生器能够在 维空间中产生一个坚硬的球体。现在,你被困在了这个 n 维球体中,你只知道球面上 个点的坐标,你需要以最快的速度确定这个 维球体的球心坐标,以便于摧毁这个球形空间产生器。
题意: 求 维点 (), 使 距离 球面上 个点的 距离相等,
使用 式子 表示出来, 即
相邻式子相减消去 , 得到
发现已经是一个 线性方程组 了,
系数
常数
于是 高斯消元 求解 .
#include<bits/stdc++.h>
#define reg register
const int maxn = 15;
int N;
double A[maxn][maxn];
double B[maxn][maxn];
int main(){
scanf("%d", &N);
for(reg int i = 1; i <= N+1; i ++)
for(reg int j = 1; j <= N; j ++) scanf("%lf", &B[i][j]);
for(reg int i = 1; i <= N; i ++){
for(reg int j = 1; j <= N; j ++) A[i][j] = 2.0*(B[i+1][j] - B[i][j]);
A[i][N+1] = 0;
for(reg int j = 1; j <= N; j ++)
A[i][N+1] += (B[i][j]+B[i+1][j])*(B[i+1][j] - B[i][j]);
}
for(reg int i = 1; i <= N; i ++){
int max_id = i;
for(reg int j = i+1; j <= N; j ++)
if(fabs(A[max_id][i]) < fabs(A[j][i])) max_id = j;
std::swap(A[i], A[max_id]);
double tmp = A[i][i];
for(reg int j = i; j <= N+1; j ++) A[i][j] /= tmp;
for(reg int j = i+1; j <= N; j ++){
tmp = A[j][i];
for(reg int k = i; k <= N+1; k ++)
A[j][k] -= A[i][k] * tmp;
}
}
for(reg int i = N; i >= 1; i --)
for(reg int j = i+1; j <= N; j ++) A[i][N+1] -= A[i][j]*A[j][N+1];
for(reg int i = 1; i <= N; i ++) printf("%.3lf ", A[i][N+1]);
return 0;
}