【高斯消元】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 }