高斯消元的应用

高斯消元是用来解决线性方程组的,也就是可以解决能够转换成线性方程组的题目:

n维圆心求解问题

  我们知道已知 n 维球上的 n+1 个点,是可以求解 n 维球心的坐标的。
假设,已知圆上(2维球)三点:
( a 1 , b 1 ) , ( a 2 , b 2 ) , ( a 3 , b 3 ) (a_1,b_1),(a_2,b_2),(a_3,b_3) (a1,b1)(a2,b2)(a3,b3)
那么我们可以得到方程组:
{ ( x − a 1 ) 2 + ( y − b 1 ) 2 = r 2 ( x − a 2 ) 2 + ( y − b 2 ) 2 = r 2 ( x − a 3 ) 2 + ( y − b 3 ) 2 = r 2 \begin{cases} (x-a_1)^2 + (y-b_1)^2 = r^2 \\(x-a_2)^2 + (y-b_2)^2 = r^2 \\(x-a_3)^2 + (y-b_3)^2 = r^2 \end{cases} (xa1)2+(yb1)2=r2(xa2)2+(yb2)2=r2(xa3)2+(yb3)2=r2
做一下减法转换:
{ 2 ( a 1 − a 2 ) x + 2 ( b 1 − b 2 ) y = ( a 1 2 − a 2 2 ) + ( b 1 2 − b 2 2 ) 2 ( a 2 − a 3 ) x + 2 ( b 2 − b 3 ) y = ( a 2 2 − a 3 2 ) + ( b 2 2 − b 3 2 ) \begin{cases} 2(a_1-a_2)x + 2(b_1-b_2)y = (a_1^2 - a_2^2) + (b_1^2 - b_2^2) \\2(a_2-a_3)x + 2(b_2-b_3)y = (a_2^2 - a_3^2) + (b_2^2 - b_3^2) \end{cases} {2(a1a2)x+2(b1b2)y=(a12a22)+(b12b22)2(a2a3)x+2(b2b3)y=(a22a32)+(b22b32)这就是我们熟知的线性方程组了,然后就gauss就行了。
拓展到 n 维:
{ 2 ( a 1 − a 2 ) x + 2 ( b 1 − b 2 ) y + … + 2 ( z 1 − z 2 ) p = ( a 1 2 − a 2 2 ) + ( b 1 2 − b 2 2 ) + … + ( z 1 2 − z 2 2 ) 2 ( a 2 − a 3 ) x + 2 ( b 2 − b 3 ) y + … + 2 ( z 2 − z 3 ) p = ( a 2 2 − a 3 2 ) + ( b 2 2 − b 3 2 ) + … + ( z 2 2 − z 3 2 ) … … 2 ( a n − 1 − a n ) x + 2 ( b n − 1 − b n ) y + … + 2 ( z n − 1 − z n ) p = ( a n − 1 2 − a n 2 ) + … + ( z n − 1 2 − z n 2 ) \begin{cases} 2(a_1-a_2)x+2(b_1-b_2)y +… + 2(z_1-z_2)p = (a_1^2 - a_2^2) + (b_1^2 - b _ 2^2)+…+(z_1^2-z_2^2) \\2(a_2-a_3)x + 2(b_2-b_3)y +… + 2(z_2-z_3)p = (a_2^2 - a_3^2) + (b_2^2 - b _ 3^2)+…+(z_2^2-z_3^2) \\…… \\2(a_{n-1}-a_n)x + 2(b_{n-1}-b_n)y +… + 2(z_{n-1}-z_n)p = (a_{n-1}^2 - a_n^2) +…+(z_{n-1}^2-z_n^2) \end{cases} 2(a1a2)x+2(b1b2)y++2(z1z2)p=(a12a22)+(b12b22)++(z12z22)2(a2a3)x+2(b2b3)y++2(z2z3)p=(a22a32)+(b22b32)++(z22z32)2(an1an)x+2(bn1bn)y++2(zn1zn)p=(an12an2)++(zn12zn2)
例题:球形空间产生器
有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。

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

输入格式
第一行是一个整数n。

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

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

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

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

数据保证有解。

数据范围
1≤n≤10
输入样例:
2
0.0 0.0
-1.0 1.0
1.0 0.0
输出样例:
0.500 1.500

#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int maxn = 110;
const int inf = 0x3f3f3f3f3f;
const double eps = 1e-7;
int n;
double a[maxn][maxn];
double b[maxn][maxn];
void gauss(){
    double del;
    for(int i=1;i<=n;i++){
        int k=i;
        for(int j=i+1;j<=n;j++){
            if(fabs(a[j][i])>fabs(a[k][i]))
                k=j;
        }
        if(fabs(del=a[k][i])<eps)   continue;
        if(i!=k){
            for(int j=i;j<=n+1;j++)
                swap(a[i][j],a[k][j]);
        }
        for(int j=i;j<=n+1;j++) a[i][j]/=del;
        for(k=1;k<=n;k++){
            if(k!=i){
                del=a[k][i];
                for(int j=i;j<=n+1;j++)
                    a[k][j] -= a[i][j]*del;
            }
        }
    }
    for(int i=1;i<=n;i++){
        printf("%.3f ",a[i][n+1]/a[i][i]);
    }
}
int main(void)
{
    scanf("%d",&n);
    for(int i=1;i<=n+1;i++){
        for(int j=1;j<=n;j++){
            scanf("%lf",&b[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            a[i][j] = 2.0*(b[i][j]-b[i+1][j]);
            a[i][n+1] += (b[i][j]*b[i][j]-b[i+1][j]*b[i+1][j]);
        }
    }
    gauss();
    return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃夭丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值