题解【AcWing883】高斯消元解线性方程组

题面

高斯消元模板题。

这里直接讲述一下高斯消元的算法流程:

  • 枚举每一列 \(c\)
  • 找到第 \(c\) 列绝对值最大的一行;
  • 将这一行换到最上面;
  • 将该行的第一个数变成 \(1\)
  • 将下面所有行的第 \(c\) 列变成 \(0\)

处理完后需要从最后一行往回迭代,求出每一个未知数的值。

#include <bits/stdc++.h>

using namespace std;

const double eps = 1e-6; //浮点数误差

int n, m;
double a[103][103];

inline int gauss()
{
    int c, r;
    //c 为每次枚举的列,r 为当前处理的行
    for (c = 0, r = 0; c < n; c+=1) //枚举每一列
    {
        int max_abs = r;
        for (int i = r + 1; i < n; i+=1)
            if (fabs(a[i][c]) > fabs(a[max_abs][c])) 
                max_abs = i; //找到第 c 列绝对值最大的一行
        if (fabs(a[max_abs][c]) < eps) continue; //这一列所有数都是 0 就不用处理
        for (int i = c; i <= n; i+=1) swap(a[max_abs][i], a[r][i]); //将这一行换到最上面
        for (int i = n; i >= c; i-=1) a[r][i] /= a[r][c]; //将这一行的第 c 列变成 1,需要将这一行的所有数都除以第 c 列的数
        for (int i = r + 1; i < n; i+=1) //将下面每一行的第 c 列变成 0 
            if (fabs(a[i][c]) > eps) //如果当前行的第 c 列大于 0
            {
                for (int j = n; j >= c; j-=1) 
                    a[i][j] -= a[r][j] * a[i][c]; //进行消除
            }
        ++r;
    }
    if (r < n) 
    {
        for (int i = r; i < n; i+=1) 
            if (fabs(a[i][n]) > eps) return 2; //无解
        return 1; //有无穷多组解
    }
    for (int i = n - 1; i >= 0; i-=1) //从下往上迭代
        for (int j = i + 1; j < n; j+=1) //枚举原矩阵
            a[i][n] -= a[j][n] * a[i][j]; //进行消除
    return 0; //有唯一解
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i+=1)
        for (int j = 0; j < n + 1; j+=1) 
            scanf("%lf", &a[i][j]);
    int t = gauss();
    if (t == 0) //有唯一解
        for (int i = 0; i < n; i+=1) printf("%.2lf\n", a[i][n]);
    else if (t == 1) //有无穷多组解
        puts("Infinite group solutions");
    else //无解
        puts("No solution");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xsl19/p/12323972.html