BZOJ1013 JSOI2008 球形空间产生器sphere 高斯消元

题意:给定N维球面上的N+1个点,求这个球的球心。
题解:无意中翻到的一道裸题,顺手做了。首先考虑一个比较简单的二维情况,对于两个点(x1,y1),(x2,y2),据题意可以得到

推广一下有

\[\sum\limits_{i = 1}^N {2({d_{a,i}} - {d_{b,i}}){x_i}}  = \sum\limits_{i = 1}^N {(d_{a,i}^2 - d_{b,i}^2)} \]

显然高斯消元可做(注意答案是全文比较,就这样了WA了一发)

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define eps 1e-6

const int MAXN=10+2;
int N;
double p[MAXN],a[MAXN][MAXN],b[MAXN],x[MAXN];

void Gauss(){
    for(int i=1,p=i;i<=N;i++,p=i){
        for(int j=i+1;j<=N;j++)
            if(fabs(a[j][i])>fabs(a[p][i])) p=j;
        for(int j=1;j<=N;j++) swap(a[p][j],a[i][j]);
        swap(b[p],b[i]);

        for(int j=i+1;j<=N;j++){
            double r=a[j][i]/a[i][i];
            for(int k=1;k<=N;k++) a[j][k]-=a[i][k]*r;
            b[j]-=b[i]*r;
        }
    }

    for(int i=N;i;i--){
        x[i]=b[i]/a[i][i];
        for(int j=i-1;j;j--) b[j]-=x[i]*a[j][i],a[j][i]=0;
    }
}

int main(){
    cin >> N;
    for(int i=1;i<=N;i++) cin >> p[i];
    for(int i=1;i<=N;i++){
        double q;
        for(int j=1;j<=N;j++){
            cin >> q;
            a[i][j]=2*(p[j]-q),b[i]+=(p[j]*p[j]-q*q);
        }
    }

    Gauss();
    for(int i=1;i<=N;i++){
        printf("%.3lf",x[i]);
        if(i!=N) cout << " ";
    }

    return 0;
}
View Code

 

posted @ 2017-02-26 02:42  WDZRMPCBIT  阅读(145)  评论(0编辑  收藏  举报