我们把球心坐标看做方程的一组解,之后我们设这个高维球体的半径是r。
这样我们可以同时列出n+1个方程:$$sum_{i=1}^n(a_i - b_i)^2 = r^2$$
把方程拆开得到$$sum_{i=1}^n(-2a_ib_i) + sum_{i=1}nb_i2 - r^2 = sum_{i=1}n-a_i2$$
因为(sum_{i=1}^nb_i^2 - r^2)是一个与球面上点无关的量,我们直接把它设为一个新的变量,系数为1即可。之后我们就套用高斯消元解方程组。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('
')
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
using namespace std;
typedef long long ll;
const int M = 100005;
const int N = 10000005;
int read()
{
int ans = 0,op = 1;char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
while(ch >='0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
return ans * op;
}
int n;
double a[15][15],ans[15];
void gauss()
{
rep(i,1,n)
{
int r = i;
rep(j,i+1,n) if(fabs(a[r][i]) < fabs(a[j][i])) r = j;
if(r != i) swap(a[i],a[r]);
double div = a[i][i];
rep(j,i,n+1) a[i][j] /= div;
rep(j,i+1,n)
{
div = a[j][i];
rep(k,i,n+1) a[j][k] -= a[i][k] * div;
}
ans[n] = a[n][n+1];
per(i,n-1,1)
{
ans[i] = a[i][n+1];
rep(j,i+1,n) ans[i] -= a[i][j] * ans[j];
}
}
}
int main()
{
n = read(),n++;
rep(i,1,n)
{
rep(j,1,n-1) scanf("%lf",&a[i][j]),a[i][n+1] -= a[i][j] * a[i][j],a[i][j] *= -2.0;
a[i][n] = 1;
}
gauss();
rep(i,1,n-1) printf("%.3lf ",ans[i]);enter;
return 0;
}