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 }