【高斯消元】BZOJ1013-[JSOI2008]球形空间产生器sphere

【题目大意】

给出n维空间中给出n+1个点的坐标,求出球心坐标。

【思路】

令球心坐标为x1,x2...xn,假设当前第i个点坐标为a1,a2...,an,第i+1个点坐标为b1,b2...,bn,则由半径相等可得:

(a1-x1)^2+(a2-x2)^2+...+(an-xn)^2=(b1-x1)^2+(b2-x2)^2+...+(bn-xn)^2

化简可得:

2(a1-b1)x1+2(a2-b2)x2+...+2(an-bn)xn=(a1^2+a2^2+...+an^2-b1^2-b2^2-...-b3^2)

如此可得到n个一元n次方程组,用最简单的高斯消元搞一搞就好了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int MAXN=15;
 8 int n;
 9 double pos[MAXN][MAXN],l[MAXN][MAXN];
10 
11 void Gauss()
12 {
13     for (int i=1;i<=n;i++)
14     {
15         int t=i;
16         for (int j=i+1;j<=n;j++) if (fabs(l[j][i])>fabs(l[t][i])) t=j;
17         if (t!=i) for (int j=i;j<=n+1;j++) swap(l[i][j],l[t][j]);
18         for (int j=i+1;j<=n;j++)
19         {
20             double x=l[j][i]/l[i][i];
21             for (int k=i;k<=n+1;k++) l[j][k]-=l[i][k]*x;
22         }
23     }
24     for (int i=n;i>=1;i--)
25     {
26         for (int j=i+1;j<=n;j++) l[i][n+1]-=l[j][n+1]*l[i][j];
27         l[i][n+1]/=l[i][i];
28     }
29 }
30 
31 
32 void init()
33 {
34     scanf("%d",&n);
35     memset(l,0,sizeof(l)); 
36     for (int i=1;i<=n+1;i++)
37         for (int j=1;j<=n;j++) 
38         {
39             scanf("%lf",&pos[i][j]);
40             if (i!=1)
41             {
42                 l[i-1][j]=2*(pos[i][j]-pos[i-1][j]); 
43                 l[i-1][n+1]+=pos[i][j]*pos[i][j]-pos[i-1][j]*pos[i-1][j];
44             }
45         }
46 }
47 
48 void print_ans()
49 {
50     for (int i=1;i<=n;i++) 
51     {
52         printf("%.3lf",l[i][n+1]);
53         if (i!=n) printf(" ");
54     }
55 }
56 
57 int main()
58 {
59     init();
60     Gauss();
61     print_ans();
62     return 0;
63 }

 

posted @ 2016-07-13 10:29  iiyiyi  阅读(444)  评论(0编辑  收藏  举报