首页 > Web开发 > 详细

[JSOI2008]球形空间产生器

时间:2019-03-24 15:58:45      阅读:136      评论:0      收藏:0      [点我收藏+]

洛咕

题意:有一个n维球体,你知道球面上n+1个点的坐标,你需要确定这个n维球体的球心坐标.

分析:对于一个球,球面上任意一点到球心的距离都是相等的,我们可以根据这条性质,列出n+1个方程。但方程右边全都是半径,而半径我们正好又不知道,所以可以通过相邻两个方程相减从而消去半径,同时也构造出了我们熟悉的n个n元一次方程。直接高斯消元(my学习笔记)

#include<bits/stdc++.h>
using namespace std;
double a[20][20],b[20][20];
int main(){
    int n;cin>>n;
    for(int i=1;i<=n+1;i++)
        for(int j=1;j<=n;j++)
            scanf("%lf",&a[i][j]);
//读入n+1个点的n维坐标
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            b[i][j]=2*(a[i][j]-a[i+1][j]);
//因为点的坐标^2-球心坐标^2=半径^2,化简一下就会有个乘2
            b[i][n+1]+=(a[i][j]*a[i][j]-a[i+1][j]*a[i+1][j]);
        }       
//构造出n个n元一次方程
    for(int i=1;i<=n;i++){//高斯消元的模板
            int now=i;
            for(int j=i+1;j<=n;j++)
                if(fabs(b[now][i])<fabs(b[j][i]))now=j;
            if(now!=i){
                for(int j=i;j<=n+1;j++)
                    swap(b[i][j],b[now][j]);
            }
            for(int j=i+1;j<=n+1;j++)
                b[i][j]/=b[i][i];
            b[i][i]=1;
            for(int j=i+1;j<=n;j++){
                for(int k=i+1;k<=n+1;k++)
                    b[j][k]-=b[j][i]*b[i][k];
                b[j][i]=0;
            }    
    }   
    for(int i=n;i>=1;i--){
        for(int j=i+1;j<=n;j++){
            b[i][n+1]-=b[i][j]*b[j][n+1];
            b[i][j]=0;
        }
    }
    for(int i=1;i<=n;i++)
        printf("%.3lf ",b[i][n+1]);
   return 0;
} 

[JSOI2008]球形空间产生器

原文:https://www.cnblogs.com/PPXppx/p/10588509.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!