其他分享
首页 > 其他分享> > Luogu P4035 [JSOI2008]球形空间产生器

Luogu P4035 [JSOI2008]球形空间产生器

作者:互联网

题目描述

有一个球形空间产生器能够在 \(n\) 维空间中产生一个坚硬的球体。现在,你被困在了这个 \(n\) 维球体中,你只知道球面上 \(n+1\) 个点的坐标,你需要以最快的速度确定这个 \(n\) 维球体的球心坐标,以便于摧毁这个球形空间产生器。

输入格式

第一行是一个整数\(n \left( 1 \le N \le 10 \right)\)。接下来的 \(n+1\) 行,每行有 \(n\) 个实数,表示球面上一点的 \(n\) 维坐标。每一个实数精确到小数点后 \(6\) 位,且其绝对值都不超过 \(20000\)。

输出格式

有且只有一行,依次给出球心的 \(n\) 维坐标( \(n\) 个实数),两个实数之间用一个空格隔开。每个实数精确到小数点后 \(3\) 位。数据保证有解。你的答案必须和标准输出一模一样才能够得分。

题目链接

思路

根据题意得

\[ (x_{1}-a_{1})^2+(x_{2}-a_{2})^2+.......+(x_{n}-a_{n})^2=r^2 \]

可化为

$ 2a_{1}x_{1}+2a_{2}x_{2}+......+2a_{n}x_{n}-r^2-x_{1}^{2}-x_{2}^{2}-......-x_{n}^{2}=a_{1}^{2}+.......a_{n}^{2} $

设 $ t=-r^2-x_{1}^{2}-x_{2}^{2}-......-x_{n}^{2} $

所以得到

$ 2a_{1}x_{1}+2a_{2}x_{2}+......+2a_{n}x_{n}+t=a_{1}^{2}+.......a_{n}^{2} $

因此可以得到一个 \(n+1\)元方程组

利用高斯消元求解,别忘了总数是 \(n+1\) 而不是 \(n\) (调了半小时的祸根)

(\(\mathrm{LaTeX}\)好难打呀)

code

#include<bits/stdc++.h>
using namespace std;
const int MAXN=20;
double a[MAXN][MAXN],num;
int n;

void debug()
{
    puts("---------------------------------");
    for(int i=1;i<=n+1;++i){
        for(int j=1;j<=n+2;++j){
            cout<<fixed<<setprecision(2)<<a[i][j]<<"    ";
        }
        putchar('\n');
    }
}

void gauss()
{
    for(int i=1;i<=n+1;i++){
//      debug();
        int now=i;
        while(a[now][i]==0&&now<=n+1){
            now++;
        }
        if(now==n+2){
            puts("???");
            exit(233);
        }
        for(int j=1;j<=n+2;j++){
            swap(a[i][j],a[now][j]);
        }
        double k=a[i][i];
        for(int j=1;j<=n+2;j++){
            a[i][j]/=k;
        }
        for(int j=1;j<=n+1;j++){
            if(j!=i){
                double kkk=a[j][i];
                for(int k=1;k<=n+2;k++){
                    a[j][k]-=kkk*a[i][k];
                }
            }
        }
        
    }
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    cin>>n;
    for(int i=1;i<=n+1;++i){
        for(int j=1;j<=n;j++){
            cin>>num;
            a[i][j]=2*num,a[i][n+2]+=num*num;
        }
        a[i][n+1]=1;
    }
    gauss();
    for(int i=1;i<=n;++i){
        cout<<fixed<<setprecision(3)<<a[i][n+2]<<' ';
    }
    return 0;
}

参考博客

标签:P4035,int,Luogu,JSOI2008,实数,num,MAXN,2a,产生器
来源: https://www.cnblogs.com/zhu-chen/p/11521433.html