我們小學學過二元一次方程組,
很明顯,我們用下面的方程減去上面的方程就能求出,然後再回代第一個方程我們就能求出,高斯消元也是基於這樣的思想。
我們可以將這個寫成增廣矩陣的形式
爲了求出解,我們只有化解爲上三角行列式,怎麼化簡呢可以這樣,可以這樣考慮,對於第 i 行來說,我們用第 i 行下面的每一行減去倍數關係使得第i行下面的每一行的第 i 列都爲0。
先不管係數,我們來看一下過程。
我們取枚舉每一行,然後用每一行下面的行,減去這一行的倍數,就能化簡爲上三角行列式。
接下來怎麼求出方程的解呢,回代。
最後一行只有一個未知數的係數不爲0,一次除法就能得到方程的解了,倒數第二行只有兩個未知數係數不爲0,將最後一行的解帶入倒數第二行,就只剩下一個未知數,一次除法就能得到倒數第二行的解了,依次類推。
爲了提高精度,我們按第i行係數絕對值從大到小進行枚舉。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100 + 7;
const double eps = 1e-8;
typedef double matrix[maxn][maxn];
int guass_elimination(matrix A, int n) // 高斯消元
{
int i, j, k, r;
for(i = 0; i < n; i++) { // 消元
r = i;
for(j = i + 1; j < n; j++) if(fabs(A[j][i]) > fabs(A[r][i])) r = j;
if(fabs(A[r][i]) < eps) return 0; // 無解
if(r != i) for(int j = 0; j <= n; j++) swap(A[i][j], A[r][j]);
for(k = i + 1; k < n; k++) {
double f = A[k][i] / A[i][i];
for(j = i; j <= n; j++) A[k][j] -= f * A[i][j];
}
}
for(i = n - 1; i >= 0; i--) { // 回代
for(j = i + 1; j < n; j++) {
A[i][n] -= A[j][n] * A[i][j];
}
A[i][n] /= A[i][i];
}
return 1;
}
int main()
{
int n;
matrix A;
while(scanf("%d", &n) == 1) {
for(int i = 0; i < n; i++) {
for(int j = 0; j <= n; j++) {
scanf("%lf", &A[i][j]);
}
}
int flag = guass_elimination(A, n);
if(flag == 0) printf("No Solution\n");
else {
for(int i = 0; i < n; i++) printf("%.2lf\n", A[i][n]);
}
}
return 0;
}