版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ronaldo7_ZYB/article/details/89816652
题目描述
有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。
现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁这个球形空间产生器。
题解
题目大意:求在n维空间中n+1个点,求解一个点的坐标使得这个点到其他每一个点的距离都相等。
这道题的难点在于数学推导,推到完以后就直接套高斯消元模板即可。
若 ,则每一个点到球心的距离 可以表示为, 为球心坐标:
显然对于每一份i来说,这一个 都是不变的。这是含有 个方程的一个二次方程组,十分难解;我们应该对其进行化简。
我们对这
个方程相减,则有:
再大力展开,即可得到:
这样我们就化简为了一个高斯消元的形式:
对于第 行来说,有 个未知数.每一行j个未知数的和为定值。
若 那个第 行第 列所对应的未知数就是 系数是 .
则是方程之积。
然后直接套高斯消元的模板即可。
#include <bits/stdc++.h>
using namespace std;
int n;
double b[100];
double a[100][100];
double c[100][100];
int main(void)
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
cin>>n;
for (int i=1;i<=n+1;++i)
for (int j=1;j<=n;++j)
cin>>a[i][j];
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];
}
double eps = 1e-8;
for (int i=1;i<=n;++i)
{
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]);
break;
}
//交换第i行和第r行
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("%.3lf ",b[i]/c[i][i]);
printf("%.3lf\n",b[n]/c[n][n]);
return 0;
}