• AcWing 207. 球形空间产生器 (高斯消元)打卡


    有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。

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

    输入格式

    第一行是一个整数n。

    接下来的n+1行,每行有n个实数,表示球面上一点的n维坐标。

    每一个实数精确到小数点后6位,且其绝对值都不超过20000。

    输出格式

    有且只有一行,依次给出球心的n维坐标(n个实数),两个实数之间用一个空格隔开。

    每个实数精确到小数点后3位。

    数据保证有解。

    数据范围

    1n101≤n≤10

    输入样例:

    2
    0.0 0.0
    -1.0 1.0
    1.0 0.0
    

    输出样例:

    0.500 1.500



    题意:n维空间,给你n+1个点,这n+1个点都在圆面上,求这个圆心坐标是多少
    思路:首先每个点都在圆面上,点到圆心的距离相等
    点与圆心的方程为 (x-a)^2+(y-b)^2 = r^2
    然后我们可以把这n+1个点带入,得出n+1个式子
    求线性方程组的算法高斯消元,但是我们还要化简成高斯消元所满足的最简式子,我们可以通过相邻两个方程减,可以得出
    2*(a11-a21)x1 + 2*(a12-a22)x2 ......2*(a1n-a2n)xn = a11^2-b11^2 + a12^2-b12^2 ...... a1n^2-b12^2
    得出n个类似的式子
    我们就可以通过高斯消元最后得出答案
    通过化成矩阵最后化成一个最简矩阵,上面就是化简的过程
    我们通过三种初等行变换进行操作来得出的答案
    1,用一个非零的数乘以这行的所有数
    2,把其中一行的x倍加到另一行
    3,交换两行的位置

    #include<bits/stdc++.h>
    #define maxn  100005
    #define mod 1000000007
    #define eps 1e-8
    using namespace std;
    typedef long long ll;
    double d[20][20],a[20][20],b[20];
    int main(){
        ll n;
        cin>>n;
        for(int i=0;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>d[i][j];
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                a[i][j]=2*(d[i-1][j]-d[i][j]);
                b[i]+=d[i-1][j]*d[i-1][j]-d[i][j]*d[i][j];
            }
        }
        
        for(int i=1;i<=n;i++){
            for(int j=i;j<=n;j++){
                if(fabs(a[j][i])>eps){//我们要选一个系数不为0的数来进行操作,这个精度一般选择在 1e-4到1e-9之间,因为有些是0的数有可能还被认为系数不为0,有些不是0还被认为是0,必须要用精度判断
                    for(int k=1;k<=n;k++){
                        double t=a[i][k];
                        a[i][k]=a[j][k];
                        a[j][k]=t;
                    }
                    double t=b[i];
                    b[i]=b[j];
                    b[j]=t;
                }
            }
    //这个题是保证有解,有可能还有两种情况,如果某一行都为0,那么就有无穷多个解,如果某一行都为0,但是常数不是0,那么就造成 0 = c 的形式,说明方程无解,这另外两种情况都需要自己判断
    for(int j=1;j<=n;j++){ if(i==j) continue; double state=a[j][i]/a[i][i]; for(int k=1;k<=n;k++){ a[j][k]-=state*a[i][k]; } b[j]-=b[i]*state; } } for(int i=1;i<=n;i++){ printf("%.3lf ",b[i]/a[i][i]); } }
    
    
    
     
  • 相关阅读:
    Windows API一日一练(55)FlushFileBuffers和SetFilePointer函数
    JDBC连接MySQL数据库及演示样例
    FusionCharts简单教程(一)---建立第一个FusionCharts图形
    破解中国电信华为无线猫路由(HG522-C)自己主动拨号+不限电脑数+iTV
    DB9 公头母头引脚定义及连接
    第二届战神杯线上编程挑战赛月赛第一题:回文数
    白话经典算法系列之七 堆与堆排序
    开发人员程序猿10大聚集地
    对不起,说句粗话——这个太屌了,windows1.0安装程序(附下载)
    Arduino入门套件 Arduino UNO R3
  • 原文地址:https://www.cnblogs.com/Lis-/p/11098053.html
Copyright © 2020-2023  润新知