[bzoj1013]球形空间产生器

第一眼看到这题完全没思路。。搜了一下题解发现就是解一个方程组。。。Orz(然而我也不会啊233)

所以说就学了一下高斯消元。。(据说高斯-约当消元法在OI中更常用)

设球心为X=[x1,x2,x3,x4,...,xn],每一个点的坐标为Ai=[ai1,ai2,ai3,...,ain]

那么根据空间距离公式可以得到(因为球心到球面上个点距离相等么。。由于等式两边相等,所以可以直接把根号给拆掉。。)

  (a11-x1)²+(a12-x2)²+(a13-x3)²+...+(a1n-xn)²=(ai1-x1)²+(ai2-x2)²+(ai3-x3)²+...+(ain-xn)²      (1<i<=n)

那么化简一下后套模板就行了。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <map>
 7 #include <string>
 8 #include <vector>
 9 #include <stack>
10 #include <cmath>
11 using namespace std;
12 
13 double x[50],y,f[50][50],s[50];
14 int n;
15 int main(){
16     scanf("%d",&n);
17     for(int i=1;i<=n;i++)scanf("%lf",&x[i]);
18     for(int i=1;i<=n;i++){
19         for(int j=1;j<=n;j++){
20             scanf("%lf",&y);
21             f[i][j]=2*(y-x[j]);
22             f[i][n+1]+=y*y-x[j]*x[j];
23         }
24     }    
25     for(int i=1;i<=n;i++){
26         int r=i;
27         for(int j=i+1;j<=n;j++)
28             if(fabs(f[j][i])>fabs(f[r][i]))
29                 r=j;
30         for(int j=1;j<=n+1;j++)swap(f[r][j],f[i][j]);
31         for(int k=i+1;k<=n;k++){
32             double t=f[k][i]/f[i][i];
33             for(int j=i;j<=n+1;j++)f[k][j]-=t*f[i][j];
34         }
35     }
36     for(int i=n;i>=1;i--){
37         for(int j=i+1;j<=n;j++)
38             f[i][n+1]-=f[j][n+1]*f[i][j];
39         f[i][n+1]/=f[i][i];
40     }
41     for(int i=1;i<=n-1;i++)printf("%.3f ",f[i][n+1]);
42     printf("%.3lf\n",f[n][n+1]);
43 }
View Code

 

posted @ 2017-01-01 10:15  KingSann  阅读(110)  评论(0编辑  收藏  举报