高斯消元是用来求线性方程组的解,行列式求值,或者矩阵求逆等等。主要有两个步骤:化行阶梯形矩阵和回带。
高斯消元的时间复杂度为,以下代码中代表方程个数,代表未知数个数,数组用来判断哪些未知数是
变元,数组用来存求得的解。
代码:
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include <math.h> using namespace std; const int N = 105; int gcd(int a,int b) { return b ? gcd(b,a%b):a; } int lcm(int a,int b) { return a / gcd(a,b) * b; } /**n个方程,m个未知数,r代表当前处理的行,c代表当前处理的列*/ void Gauss(int a[][N],int n,int m,int &r,int &c) { r = c = 0; for(; r<n && c<m; r++,c++) { int maxi = r; for(int i=r+1; i<n; i++) if(abs(a[i][c]) > abs(a[maxi][c])) maxi = i; if(maxi != r) { for(int i=r; i<m+1; i++) swap(a[r][i],a[maxi][i]); } if(a[r][c] == 0) { r--; continue; } for(int i=r+1; i<n; i++) { if(a[i][c] != 0) { int x = abs(a[i][c]); int y = abs(a[r][c]); int LCM = lcm(x,y); int tx = LCM / x; int ty = LCM / y; if(a[i][c] * a[r][c] < 0) ty = -ty; for(int j=c; j<m+1; j++) a[i][j] = a[i][j] * tx - a[r][j] * ty; } } } } int Rewind(int a[][N],int x[],bool f[],int n,int m,int r,int c) { for(int i=r; i<n; i++) if(a[i][c] != 0) return -1; if(r < m) { memset(f,1,sizeof(f)); for(int i=r-1; i>=0; i--) { int id = 0; int cnt = 0; for(int j=0; j<m; j++) { if(a[i][j] != 0 && f[j]) { cnt++; id = j; } } if(cnt > 1) continue; int t = a[i][m]; for(int j=0; j<m; j++) { if(a[i][j] != 0 && j != id) t -= a[i][j] * x[j]; } x[id] = t / a[i][id]; f[id] = 0; } return m - r; } for(int i=r-1; i>=0; i--) { int t = a[i][c]; for(int j=i+1; j<c; j++) { if(a[i][j] != 0) t -= a[i][j] * x[j]; } if(t % a[i][i] != 0) return -2; x[i] = t / a[i][i]; } return 0; } void Print(int a[][N],int n,int m) { for(int i=0; i<n; i++) { for(int j=0; j<m+1; j++) cout<<a[i][j]<<" "; cout<<endl; } } int a[N][N]; int x[N]; bool f[N]; int main() { int n,m; while(cin>>n>>m) { for(int i=0; i<n; i++) { for(int j=0; j<m+1; j++) cin>>a[i][j]; } int r,c; Gauss(a,n,m,r,c); Rewind(a,x,f,n,m,r,c); Print(a,n,m); puts(""); } return 0; }