基础高斯消元模板

基础高斯消元模板

基础的高斯消元模板就是个模拟,就是在模拟手算,将一个增广矩阵变成一个阶梯型矩阵,然后变换完之后即可得到秩,然后根据秩的大小我们就可以知道有没有唯一解,如果有唯一解就不断的回带,最终得到这组唯一解。这些都是线代的知识,学习这个模板前把相关的线代知识学透再来学这个模板真的就会非常清晰,或者说最好是先理解透线代的有关于高斯消元的知识再来学习这个模板,而不是从这个模板种学习高斯消元。

模板题链接

#include <bits/stdc++.h>

using namespace std;

const int N = 1e2 + 5;

const double eps = 1e-6;

int n;

double m[N][N], x[N];

bool gauss(int n) {
    int i = 1, j = 1;
    while(i <= n && j <= n) {
        double mx = fabs(m[i][j]); int idx = i;
        for (int k = i + 1; k <= n; ++k) { //找最大的值首先是把这一列不等于0的换上来
            if (fabs(m[k][j]) > mx) { //取max的原因,实际上只要不等于0的就行了,但是反正也要找一遍max去判断是否全0,那么干脆用max那一行也行
                mx = fabs(m[k][j]);
                idx = k;
            }
        }
        if (fabs(mx) < eps) { //在此列找不到有值的行,换一列找
            j++;
            continue;
        }
        if (idx != i) { //交换两行,实际应当交换整个两行,但是其j-1前面肯定都是0了,交换了也没什么意义
            for (int k = j; k <= n + 1; ++k) {
                swap(m[i][k], m[idx][k]);
            }
        }
        for (int k = i + 1; k <= n; ++k) { //将m[i][j]垂直下方的元素都变成0
            double t = m[k][j] / m[i][j];
            m[k][j] = 0;
            for (int l = j + 1; l <= n + 1; ++l) {
                m[k][l] -= t * m[i][l];
            }
        }
        i++, j++;
    }
    for (int k = i + 1; k <= n; ++k) {
        if (fabs(m[k][n + 1]) > eps) return false; //出现非法情况
    }
    if (i != n + 1) return false; //不满秩,则有无穷多解
    for (int k = n; k >= 1; --k) { //不断回带求解
        double t = m[k][n + 1];
        for (int l = k + 1; l <= n; ++l) {
            t -= m[k][l] * x[l];
        }
        x[k] = t / m[k][k];
    }
    return true;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n + 1; ++j) {
            scanf("%lf", &m[i][j]);
        }
    }
    if (!gauss(n)) {
        puts("No Solution");
    }
    else {
        for (int i = 1; i <= n; ++i) {
            printf("%.2f\n", x[i]);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值