bzoj1013: [JSOI2008]球形空间产生器sphere (高斯消元)

题意

已知 n+1 n + 1 个点的坐标,求球心坐标


题解

我们可以通过 2n 2 − n 个点,与第一个点列出方程组
(xi,1a1)2+(xi,2a2)2++(xi,nan)2=(x1,1a1)2+(x1,2a2)2++(x1,nan)2 ( x i , 1 − a 1 ) 2 + ( x i , 2 − a 2 ) 2 + ⋯ + ( x i , n − a n ) 2 = ( x 1 , 1 − a 1 ) 2 + ( x 1 , 2 − a 2 ) 2 + ⋯ + ( x 1 , n − a n ) 2
解出 2(x1,1xi,1)a1+2(x2,1xi,2)a2++2(x1,nxi,n)an=x21,1+x21,2++x1,nx2i,1x2i,2x2n,2 2 ( x 1 , 1 − x i , 1 ) a 1 + 2 ( x 2 , 1 − x i , 2 ) a 2 + ⋯ + 2 ( x 1 , n − x i , n ) a n = x 1 , 1 2 + x 1 , 2 2 + ⋯ + x 1 , n − x i , 1 2 − x i , 2 2 − x n , 2 2
这样可以列出 n n <script type="math/tex" id="MathJax-Element-12">n</script> 个方程,高斯消元解方程就可以啦


代码

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define eps 1e-6
double a[22][22],f[22];
int n;
void gauss(){
    int now=1;
    for(int i=1;i<=n+1;i++){
        int to=now;for(int j=now+1;j<=n;j++) if(fabs(a[i][to])<fabs(a[i][j])) to=j;
        if(fabs(a[i][to])<eps)continue;
        if(to!=now) for(int j=i;j<=n+1;j++) swap(a[now][j],a[to][j]); 
        for(int j=n+1;j>=i;j--) a[now][j]/=a[now][i];
        for(int j=1;j<=n;j++)
            if(j!=now)
                for(int k=n+1;k>=i;k--) a[j][k]-=a[j][i]*a[now][k];
        now++;
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lf",&f[i]);
    for(int i=1;i<=n;i++){
        a[i][n+1]=0;
        for(int j=1;j<=n;j++){
            double x;scanf("%lf",&x);
            a[i][j]=2*(x-f[j]);a[i][n+1]+=x*x-f[j]*f[j];
        }
    }
    gauss();
    printf("%.3lf",a[1][n+1]);for(int i=2;i<=n;i++) printf(" %.3lf",a[i][n+1]);
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值