bzoj 1013
高斯消元裸题
设给出的每一组坐标为$(a_i1,a_i2,...,a_in)(i\in[1,n+1])$,设球心坐标为$(x_1,x_2,...,x_n)$
设每个点到球心的距离为$d_i$
那么一定有方程:
$d_1==d_2$
$d_2==d_3$
...
$d_n==d_n+1$
展开之后,就是:
$\sum_{i=1}^{n}(a_{1i}-x_{i})^2==\sum_{i=1}^{n}(a_{2i}-x_{i})^2$
...
$\sum_{i=1}^{n}(a_{ni}-x_{i})^2==\sum_{i=1}^{n}(a_{(n+1)i}-x_{i})^2$
不要担心平方项,因为他们要么可以约掉要么是常值
所以整理之后就是这样:
$\sum_{i=1}^{n}2*(a_{2i}-a_{1i})*x_i==\sum_{i=1}^{n}(a_{2i}^2-a_{1i}^2)$
...
$\sum_{i=1}^{n}2*(a_{(n+1)i}-a_{ni})*x_i==\sum_{i=1}^{n}(a_{(n+1)i}^2-a_{1i}^2)$
那么就是高斯消元裸题了嘛
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> using namespace std; const double eps=0.000001; double a[15][15]; double x[15][15]; int n; void Gauss() { for(int i=1;i<=n;i++) { int temp=i; while(fabs(a[temp][i])<=eps)temp++; if(temp!=i)for(int j=i;j<=n+1;j++)swap(a[temp][j],a[i][j]); double now=a[i][i]; for(int j=i;j<=n+1;j++)a[i][j]/=now; for(int j=i+1;j<=n;j++) { now=a[j][i]; for(int k=i;k<=n+1;k++)a[j][k]-=now*a[i][k]; } } for(int i=n;i>=1;i--) { for(int j=i-1;j>=1;j--)a[j][n+1]-=a[i][n+1]*a[j][i]; } } int main() { scanf("%d",&n); for(int i=1;i<=n+1;i++) { for(int j=1;j<=n;j++)scanf("%lf",&x[i][j]); if(i!=1)for(int j=1;j<=n;j++)a[i-1][j]=2.0*(x[i][j]-x[i-1][j]),a[i-1][n+1]+=x[i][j]*x[i][j]-x[i-1][j]*x[i-1][j]; } Gauss(); for(int i=1;i<=n;i++)printf("%.3lf ",a[i][n+1]); printf("\n"); return 0; }