[AcWing]883. 高斯消元解线性方程组(C++实现)高斯消元解线性方程组模板题

[AcWing]883. 高斯消元解线性方程组(C++实现)高斯消元解线性方程组模板题

  • 1. 题目
  • 2. 读题(需要重点注意的东西)
  • 3. 解法
  • 4. 可能有帮助的前置习题
  • 5. 所用到的数据结构与算法思想
  • 6. 总结

1. 题目

[AcWing]883. 高斯消元解线性方程组(C++实现)高斯消元解线性方程组模板题_第1张图片

2. 读题(需要重点注意的东西)

思路:

即模拟线性代数的求通解过程
[AcWing]883. 高斯消元解线性方程组(C++实现)高斯消元解线性方程组模板题_第2张图片
注:高斯消元中的① ② ③ ④ 对应代码中注释的① ② ③ ④

3. 解法

---------------------------------------------------解法---------------------------------------------------

#include 
#include 
#include 

using namespace std;

const int N = 110;
/*  C++浮点数存在误差,不能直接判断0,要判断是否小于一个很小的数,
    如果小于这个很小的数,就认为是0,如小于1e-6*/
const double eps = 1e-6;

int n;
double a[N][N];


int gauss()
{
     
    int c, r;// c列,r行
    for (c = 0, r = 0; c < n; c ++ )
    {
     
        int t = r;
        // ① 找到当前这一列中绝对值最大的一行
        for (int i = r; i < n; i ++ )
            if (fabs(a[i][c]) > fabs(a[t][c]))
                t = i;
        // 如果这一列中最大值已经是0了,直接continue进入下一列
        if (fabs(a[t][c]) < eps) continue;
        
        // ② 将这行换到最上面
        // 从当前列c开始交换后面的值到第一行
        for (int i = c; i < n + 1; i ++ ) swap(a[t][i], a[r][i]);
        // ③ 将该行第一个数变成1
        // 将r行中c列后的每一个元素除上一个a[r][c](该行的第一个不为零的元素)
        for (int i = n; i >= c; i -- ) a[r][i] /= a[r][c];
        
        // ④ 用这一行将下面每一行的该列清0
        for (int i = r + 1; i < n; i ++ )
            // 如果该行的该列元素不是0才进行操作
            if (fabs(a[i][c]) > eps)
                for (int j = n; j >= c; j -- )
                    a[i][j] -= a[r][j] * a[i][c];

        r ++ ; // r表示消0后最后剩余的行数
    }
    
    // 无解和无穷多解的判断
    if (r < n)
    {
     
        // 如果出现了等号左右一个为0一个非0,则说明无解
        for (int i = r; i < n; i ++ )
            if (fabs(a[i][n]) > eps)
                return 2;
        // 否则说明有无穷多解
        return 1;
    }
    
    // 回溯计算每个值xi
    for (int i = n - 1; i >= 0; i -- )
        for (int j = i + 1; j < n; j ++ )
            a[i][n] -= a[j][n] * a[i][j];
    
    // 有唯一解
    return 0;
}

int main()
{
     
    cin >> n;
    // 存储线性方程组的增广矩阵
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n + 1; j ++ )
            cin >> a[i][j];
    // 执行高斯消元
    int t = gauss();
    
    // 如果 t = 0,有唯一解
    if (t == 0)
    {
        // %.2lf 保留两位小数
        for (int i = 0; i < n; i ++ ) printf("%.2lf\n", a[i][n]);
    }
    // 如果 t = 1,线性方程组存在无数解
    else if (t == 1) puts("Infinite group solutions");
    // 否则无解
    else puts("No solution");

    return 0;
}

4. 可能有帮助的前置习题

5. 所用到的数据结构与算法思想

  • 高斯消元

6. 总结

高斯消元解线性方程组模板题,理解思路并背下代码。

你可能感兴趣的:(AcWing学习日记,c++,线性代数)