高斯-约旦消元法学习笔记
不需要回代求解 很简单
具体过程如下:
- 对于当前主元 找到它系数最大的那行
- 通过加减消元 把其它行该主元的系数干掉
- 没了
时间复杂度 \(\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
*/