在线性代数中学习了矩阵之后,高斯消元的思路就非常清晰了。
其实就是小学学习的多元方程的加减消元法。
当未知数的个数很大时,把系数提取出来写成矩阵的形式非常直观。
具体地,依次利用加减消元消去方程的每一项。每次选取当前项不为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; }