高斯消元例题
题目要求的是球心的 n 维坐标,给了n+1个点的坐标,用二维的圆来思考,n+1个点到圆心的距离相等,可以列出n+1个等式
√∑(a~i,j~-bj)^2^=r(r为半径)
两边同时平方得到∑(a~i,j~-b~j~)^2^=r^2^
因为a~i,j~已知,所以有n+1个二次方程来解n维坐标和r。
考虑学过的算法并没有高效解多个二次方程的方法,只有高斯消元解线性方程组,所以要去掉二次项。
因为有n+1个方程但真正要求的只有n个数,考虑做差消去二次项。
第i+1去减i可以得到∑2b~j~*(a~i,j~-a~i+1,j~)=∑a~i,j~^2^-a~i+1,j~^2^
n个一元一次方程,n个未知数,高斯消元求解即可。
#include <bits/stdc++.h>
using namespace std;
double a[20][20],b[20][20];
int n;
void ycl()
{
for(int i=1;i<=n+1;i++)
{
double ans=0;
for(int j=1;j<=n;j++)
scanf("%lf",&a[i][j]),ans+=a[i][j]*a[i][j];
a[i][n+1]=ans;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
b[i][j]=2*(a[i][j]-a[i+1][j]);
b[i][n+1]=a[i+1][n+1]-a[i][n+1];
}
}
int main()
{
scanf("%d",&n);
ycl();
for(int i=1;i<=n;i++)
{
int mx=i;
for(int j=i+1;j<=n;j++)
{
if(fabs(b[j][i])>fabs(b[mx][i]))mx=j;
}
swap(b[i],b[mx]);
for(int j=1;j<=n;j++)
{
if(j==i)continue;
double div=b[j][i]/b[i][i];
for(int k=i;k<=n+1;k++)b[j][k]-=b[i][k]*div;
}
}
for(int i=1;i<=n;i++)
{
printf("%.3lf ",-1*b[i][n+1]/b[i][i]);
}
return 0;
}