bzoj1013/luogu4035 球形空间生成器 (高斯消元)

根据各点到圆心的距离相等,可以列出有N个等号的方程

假设圆心坐标是(x,y,z,...)的话,$x^2,y^2,z^2$等是可以消掉的

于是整理一下,就变成了N元1次方程组,有N个方程、而且保证是相容的

高斯消元的话,就是拿着第一式去把剩下的第一项都消了,再拿第二式把剩下的第二项都消了,...到最后方程组呈一个阶梯状,然后从最后一点点往回带就能解出来

复杂度$O(n^3)$

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=15;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14 
15 int N;
16 double pos[maxn][maxn],a[maxn][maxn],b[maxn];
17 
18 int main(){
19     //freopen("","r",stdin);
20     int i,j,k;
21     N=rd();
22     for(i=1;i<=N+1;i++){
23         for(j=1;j<=N;j++){
24             scanf("%lf",&pos[i][j]);
25         }
26         if(i>1){
27             for(j=1;j<=N;j++){
28                 a[i-1][j]=2*(pos[i][j]-pos[i-1][j]);
29                 a[i-1][N+1]+=pos[i][j]*pos[i][j]-pos[i-1][j]*pos[i-1][j];
30             }
31         }
32     }
33     for(i=1;i<=N;i++){
34         for(j=i+1;j<=N;j++){
35             double p=a[j][i]/a[i][i];
36             for(k=i;k<=N+1;k++){
37                 a[j][k]-=p*a[i][k];
38             }
39         }
40     }
41     for(i=N;i;i--){
42         double r=a[i][N+1];
43         for(j=N;j>i;j--){
44             r-=b[j]*a[i][j];
45         }
46         b[i]=r/a[i][i];
47     }
48     for(i=1;i<=N;i++)
49         printf("%.3lf ",b[i]);
50     return 0;
51 }

 

posted @ 2018-10-09 10:20  Ressed  阅读(147)  评论(0编辑  收藏  举报