BZOJ1013 球形空间产生器sphere
Description
有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁这个球形空间产生器。
Input
第一行是一个整数,n。接下来的n+1行,每行有n个实数,表示球面上一点的n维坐标。每一个实数精确到小数点后6位,且其绝对值都不超过20000。
思路:可以列出方程,由于从球上每个点到球心的距离相等,所以两两相减可以刚好列出n个方程,接下来就可以高斯消元了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<string> 6 #include<algorithm> 7 double a[20][20],f[20],t,eps=1e-8; 8 int n; 9 double sqr(double x){ 10 return x*x; 11 } 12 void gauss(){ 13 int now=1,to;double t; 14 for (int i=1;i<=n;i++){ 15 for (to=now;to<=n;to++) if (fabs(a[to][i])>eps) break; 16 if (to>n) continue; 17 if (to!=now) 18 for (int j=1;j<=n+1;j++) 19 std::swap(a[to][j],a[now][j]); 20 t=a[now][i]; 21 for (int j=1;j<=n+1;j++) a[now][j]/=t; 22 for (int j=1;j<=n;j++) 23 if (j!=now){ 24 t=a[j][i]; 25 for (int k=1;k<=n+1;k++) 26 a[j][k]-=t*a[now][k]; 27 } 28 now++; 29 } 30 } 31 int main(){ 32 scanf("%d",&n); 33 for (int i=1;i<=n;i++) 34 scanf("%lf",&f[i]); 35 for (int i=1;i<=n;i++){ 36 for (int j=1;j<=n;j++){ 37 scanf("%lf",&t); 38 a[i][j]=2*(t-f[j]); 39 a[i][n+1]+=sqr(t)-sqr(f[j]); 40 } 41 } 42 gauss(); 43 for (int i=1;i<=n-1;i++) 44 printf("%.3f ",a[i][n+1]); 45 printf("%.3f\n",a[n][n+1]); 46 }