在线性代数中学习了矩阵之后,高斯消元的思路就非常清晰了。

其实就是小学学习的多元方程的加减消元法。

当未知数的个数很大时,把系数提取出来写成矩阵的形式非常直观。

具体地,依次利用加减消元消去方程的每一项。每次选取当前项不为0的一项,然后把其他的方程通过加减消元消去这一项。如果发现未处理的所有方程中当前项均为0,则此方程组无解或有无穷组解。

模板:洛谷p3389

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#include<cmath>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
const double eps=1e-7;
double a[200][200];
int p[200];
double ans[200];
bool f[200];

int main(){
    int n;
    scanf("%d",&n);
    rep(i,1,n)rep(j,1,n+1)scanf("%lf",&a[i][j]);
    rep(i,1,n){
        bool flag=false;int v;
        rep(j,1,n)if(!f[j]&&fabs(a[j][i])>eps){flag=true;p[i]=v=j;f[j]=1;break;}//p[i]记录方程处理顺序,这样就不用把当前需要处理的方程暴力提前了
        if(!flag){printf("No Solution\n");return 0;}
        rep(j,i+1,n+1)a[v][j]/=a[v][i];a[v][i]=1;
        rep(k,1,n)if(!f[k]&&fabs(a[k][i])>eps){
            rep(j,i+1,n+1)a[k][j]/=a[k][i];a[k][i]=0;
            rep(j,i+1,n+1)a[k][j]-=a[v][j];
        }
    }
    dep(i,n,1){//按照处理顺序的倒序依次解方程
        dep(j,n,i+1)a[p[i]][n+1]-=a[p[i]][j]*ans[j];
        ans[i]=a[p[i]][n+1];
    }
    rep(i,1,n)printf("%.2lf\n",ans[i]);
    return 0;
}