Luogu4035 / BZOJ1013 [JSOI2008]球状空間生成

トピックポータル

アルゴリズム分析

未知と仮定することができる\(D \)の各点を球の中心までの距離を表し、未知の提供(B_1、B_2、\ cdots \を 、B_N \) 球の中心の座標を表します。

私たちは、簡単に取得することができます(N + 1 \)\方程式:

\ [D ^ 2 = \ sum_ {i = 1} ^ {N(a_iを-b_i)^ 2} \]

二次項を発生することが判明し、ここで明らかに変換する方法は、次項を置き換えるために使用することができませんでした。

私たちは、この式を開始しました:

\ [D ^ 2 = \ sum_ {i = 1} ^ nは{a_iを^ 2} + \ sum_ {i = 1} ^ {N b_i ^ 2} +2回\ \ sum_ {i = 1} ^ {N a_ib_i } \]

不明同じ側に書いています:

\ [ - 2 \回\ sum_ {i = 1} ^ nは{a_ib_i} - \ sum_ {i = 1} ^ nは{b_i ^ 2} + D ^ 2 = \ sum_ {i = 1} ^ nは{a_iを^ 2} \]

その後、我々は各方程式、二次係数のためにすべて同じであるので、我々はキャンセル用語はオルト検討し、次のよう求め、ことがわかります\(N- \) 方程式を

\ [ - 2 \回\ sum_ {i = 1} ^ N {(a_iを-A_ {I-1})b_i} = \ sum_ {i = 1} ^ nは{a_iを^ 2-A_ {I-1} ^ 2} \]

これはガウスの消去法の条件に沿ったものである、あなたが直接行うことができます。

コードの実装

#include<bits/stdc++.h>
using namespace std;
#define maxn 105
int n;
double a[maxn][maxn],b[maxn][maxn],x[maxn][maxn];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n+1;i++){
        for(int j=1;j<=n;j++){
            scanf("%lf",&x[i][j]);
        }
    }
    for(int i=1;i<=n+1;i++){
        for(int j=1;j<=n;j++){
            b[i][j]=(-2)*x[i][j];
        }
        for(int j=1;j<=n;j++)b[i][n+1]-=(x[i][j]*x[i][j]);
    }
    for(int i=1;i<=n+1;i++){
        for(int j=2;j<=n+1;j++){
            a[i][j]=b[i][j]-b[i-1][j];
        }
    }
    for(int i=1;i<=n;i++){
        int p=0;
        for(int j=i;j<=n;j++){if(a[j][i]){p=j;break;}}
        if(!p)continue;
        for(int j=1;j<=n+1;j++)swap(a[i][j],a[p][j]);
        double k=a[i][i];
        for(int j=1;j<=n+1;j++)a[i][j]/=k;
        for(int j=1;j<=n;j++){
            if(i==j)continue;
            double kk=a[j][i];
            for(int l=1;l<=n+1;l++)a[j][l]-=kk*a[i][l];
        }
    }
    for(int i=1;i<=n;i++)printf("%.3lf ",a[i][n+1]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/ZigZagKmp/p/11491053.html