算法步驟 枚舉每一列 c: ① 找到列 c 絕對值最大的一行 ② 將該行換到最上面 ③ 將該行第一個數變成 1 (即第 c 列的數變成 1) ④ 將下面所有行第 c 列消成 0 例
典例:AcWing 883.高斯消元解線性方程組
#include<iostream>#include<algorithm>#include<cmath>usingnamespace std;constint N =110;constdouble eps =1e-6;//浮點數存儲是有誤差的,如果x < eps,我們就認為x = 0double a[N][N];int n;intgauss(){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,說明這一列所有系數都為0if(fabs(a[t][c])< eps)continue;//把絕對值最大的這行(即第t行)換到當前最上面一行(第r行)for(int i = c; i <= n ; i ++)swap(a[t][i],a[r][i]);//把當前行(即第r行)的第一個數變成1,即同時除以該行第一個數//注意這里要從后往前更新,如果先更新第1個數就不對了for(int i = n; i >= c; i --) a[r][i]/= a[r][c];//把下面所有行的第c列消成0for(int i = r +1; i < n; i ++)if(fabs(a[i][c])> eps)//如果已經是0 ,就不用消了for(int j = n; j >=c; j --)a[i][j]-= a[r][j]* a[i][c];r ++;}//最終得到方程個數小于n個,說明不是唯一解,需要判斷是無解還是無窮多組解if(r < n){for(int i = r; i < n; i ++)if(fabs(a[i][n])> eps)// 0 = 非零,無解return2;return1;//有無窮多組解}//有唯一解,從下向上回代,依次求解 for(int i = n -1; i >=0; i --)for(int j = i +1; j < n; j ++)a[i][n]-= a[i][j]* a[j][n];return0;//有唯一解}intmain(){cin >> n;for(int i =0; i < n; i ++)for(int j =0; j < n +1; j ++)cin >> a[i][j];int t =gauss();if(t ==0)//唯一解{for(int i =0; i < n; i ++)printf("%.2lf\n",a[i][n]);}elseif(t ==1)puts("Infinite group solutions");//無窮多組解elseputs("No solution");//無解return0;}