高斯-约旦消元法学习笔记

不需要回代求解 很简单
具体过程如下:

  1. 对于当前主元 找到它系数最大的那行
  2. 通过加减消元 把其它行该主元的系数干掉
  3. 没了

时间复杂度 \(\text {O}(n ^ 3)\)

#include <bits/stdc++.h>
#define db double
using namespace std;

namespace steven24 {

const int N = 1e2 + 5;
const double eps = 1e-16;
db a[N][N];
int n;

void main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= n + 1; ++j) scanf("%lf", &a[i][j]);
	}
	
	for (int i = 1; i <= n; ++i) { //查询第i个未知数的最大系数 
		int maxid = i;
		for (int j = i + 1; j <= n; ++j) {
			if (fabs(a[j][i]) > fabs(a[maxid][i])) maxid = j;
		}
		
		for (int j = 1; j <= n + 1; ++j) swap(a[i][j], a[maxid][j]); //把第i行和这个系数最大行互换
		if (fabs(a[i][i] - 0) <= eps) { //如果最大系数都是0说明无解 
			printf("No Solution\n");
			return;
		}
		
		for (int j = 1; j <= n; ++j) { //把除了第i行以外的所有行 通过加减消元把第i个未知数消掉 
			if (j == i) continue;
			db tmp = a[j][i] / a[i][i];
			for (int k = i; k <= n + 1; ++k) a[j][k] -= tmp * a[i][k]; //因为对于第j行的第i个未知数 前i - 1个未知数都在之前被消成0了 所以从第i列开始消即可 
		}
	}
	
	for (int i = 1; i <= n; ++i) printf("%.2lf\n", a[i][n + 1] / a[i][i]);
}

}

int main() {
	steven24::main();
	return 0;
}
/*
3
1 3 4 5
1 4 7 3
9 3 2 2
*/
posted @ 2023-09-04 19:17  Steven24  阅读(12)  评论(0编辑  收藏  举报