总所周知,一个球体上的所有的点到球心的距离(即半径)是相等的.
我们假设球心的坐标为,半径为
(
为常数), 并记这n + 1个点的坐标为
显然,
, 首先,这个方程是一定有解的,因为一共有n + 1个方程和n + 1个未知数(球心的坐标和半径大小),但是这是一个二元方程组,要直接解出来还是有点麻烦的,于是我们可以对相邻的两个方程作差进行消元.得到:
移项得,
```
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
const double eps = 1e-8;
double a[N][N], b[N], c[N][N];
int n;
signed main(){
cin >> n;
for (int i = 1; i <= n + 1; ++i)
for (int j = 1; j <= n; ++j)
cin >> a[i][j];
/* c:系数矩阵, b:常数,二者构成增广矩阵 */
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j){
c[i][j] = 2 * (a[i][j] - a[i + 1][j]);
b[i] += a[i][j] * a[i][j] -a[i + 1][j] * a[i + 1][j];
}
/* 高斯消元 */
/* 枚举每一列, 行数和列数是相等的(不包含最后的常数项) */
for (int i = 1; i <= n; ++i){
/* 找到x[i]系数不为0的一个方程 */
for (int j = i; j <= n; ++j){
if (fabs(c[j][i]) > eps){
for (int k = 1; k <= n; ++k)
swap(c[i][k], c[j][k]);
swap(b[i], b[j]);
}
}
/* 消去其他方程x[i]的系数 */
for (int j = 1; j <= n; ++j){
if (i == j)
continue;
double rate = c[j][i] / c[i][i];
for (int k = i; k <= n; ++k)
c[j][k] -= c[i][k] * rate;
b[j] -= b[i] * rate;
}
}
for (int i = 1; i <= n; ++i)
printf("%.3f ", b[i] / c[i][i]);
}
```