【模板】高斯消元

本文通过一个具体的线性方程组例子介绍了如何使用高斯消元法求解线性方程组。从方程组到增广矩阵的转换开始,逐步展示了如何通过初等变换将矩阵化为上三角矩阵,并最终求解出未知数的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址:戳这
上面那个是假的,数据太水,不过可以做做,来看看真题
这才是真题,数据比刚刚那道强多了

首先来看一道例题:

{ 3 x + 2 y + z = 6 2 x + 2 y + 2 z = 4 4 x − 2 y − 2 z = 2 \begin{cases} 3x+2y+z=6\\ 2x+2y+2z=4\\ 4x-2y-2z=2\\ \end{cases} 3x+2y+z=62x+2y+2z=44x2y2z=2

大家会觉得这到题是初中水题,看一眼就出来了,甚至有些人小学就会了。但是你们有没有想过如果有很多未知数的话怎么办能,手动消元?怎么可能。这复杂度太高了。于是便把目光转向了计算机。没错计算机可以很快的算出答案,但是计算机却没有人类这种思路,不能看题而来,而是去编写一个程序,来面对所有的问题。接下来就用这到题来讲讲高斯消元

  • 首先我们用矩阵来进行高斯消元。先把方程写成如下形式:
    (3) [ 3 2 1 6 2 2 2 6 4 2 2 6 ] \left[ \begin{matrix} 3 & 2 & 1 & 6 \\ 2 & 2 & 2 & 6 \\ 4 & 2 & 2 & 6 \end{matrix} \right] \tag{3} 324222122666(3)

  • 第二步对矩阵进行初等变换,初等变换包括如下几个操作:

  1. 将某行同乘或同除一个非零实数
  2. 将某一行加到另一行
  • 第三步将矩阵变为上三角矩阵,就是把主对角线全变为1,主对角线下的数都变为零。形式如下:
    (3) [ 1 2 3 1 3 2 0 1 2 0 0 0 1 − 3 ] \left[ \begin{matrix} 1 & \frac 23 & \frac 13 & 2 \\ 0 & 1 & 2 & 0 \\ 0 & 0 & 1 & -3 \end{matrix} \right] \tag{3} 10032103121203(3)

到这一步后就差不多没了,只要从最后一行往上带求出每个接并存入数组中就可以了

但是要注意一点,每次消元的时候找系数最大的那个。

代码如下

#include<bits/stdc++.h>
using namespace std;
double a[101][101];
int ABS(double x){
    return x<0?-x:x;
}
int main() {
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n+1; j++)
            scanf("%lf",&a[i][j]);
    for(int i=1; i<=n; i++) {
        int bj=i;
        for(int j=i+1; j<=n; j++)
            if(ABS(a[j][i])>ABS(a[bj][i]))
                bj=j;
        for(int j=1; j<=n+1; j++)
            swap(a[bj][j],a[i][j]);//找到系数最大的一个
        if(!a[i][i])
            continue;
        double p=a[i][i];
        for(int j=1;j<=n+1;j++)
            a[i][j]/=p;
        for(int j=1;j<=n;j++)
            if(i!=j){
                double o=a[j][i];
                for(int k=1;k<=n+1;k++)
                    a[j][k]-=a[i][k]*o;
            }
    }
    int bj2=0,bj1=0;
    for(int i=1; i<=n; i++) {
        int ans=0;
        for(int j=1; j<=n+1; j++) {
            if(!a[i][j])
                ans++;
        }
        if(ans==n&&a[i][n+1])
            bj2=1;
        
        if(ans==n+1)
            bj1=1;
    }
    if(bj2)
        printf("-1"),exit(0);//无解,因为在一行中的未知数系数为0,但结果不为0
    if(bj1)
        printf("0"),exit(0);//有无数解,因为在一行中的未知数系数为0,但结果为0。所以和未知数无关,答案一直为0,所以无论去未知数何值都满足条件
    for(int i=n-1; i>=1; i--)
        for(int j=i+1; j<=n; j++)
            a[i][n+1]-=a[j][n+1]*a[i][j];//往回带,求出答案
    for(int i=1; i<=n; i++) {
        if(a[i][n+1]==0)
            printf("x%d=0\n",i);
        else
            printf("x%d=%.2lf\n",i,a[i][n+1]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值