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 }

 

posted @ 2016-05-30 21:28  GFY  阅读(274)  评论(0编辑  收藏  举报