基础高斯消元模板
基础的高斯消元模板就是个模拟,就是在模拟手算,将一个增广矩阵变成一个阶梯型矩阵,然后变换完之后即可得到秩,然后根据秩的大小我们就可以知道有没有唯一解,如果有唯一解就不断的回带,最终得到这组唯一解。这些都是线代的知识,学习这个模板前把相关的线代知识学透再来学这个模板真的就会非常清晰,或者说最好是先理解透线代的有关于高斯消元的知识再来学习这个模板,而不是从这个模板种学习高斯消元。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e2 + 5;
const double eps = 1e-6;
int n;
double m[N][N], x[N];
bool gauss(int n) {
int i = 1, j = 1;
while(i <= n && j <= n) {
double mx = fabs(m[i][j]); int idx = i;
for (int k = i + 1; k <= n; ++k) { //找最大的值首先是把这一列不等于0的换上来
if (fabs(m[k][j]) > mx) { //取max的原因,实际上只要不等于0的就行了,但是反正也要找一遍max去判断是否全0,那么干脆用max那一行也行
mx = fabs(m[k][j]);
idx = k;
}
}
if (fabs(mx) < eps) { //在此列找不到有值的行,换一列找
j++;
continue;
}
if (idx != i) { //交换两行,实际应当交换整个两行,但是其j-1前面肯定都是0了,交换了也没什么意义
for (int k = j; k <= n + 1; ++k) {
swap(m[i][k], m[idx][k]);
}
}
for (int k = i + 1; k <= n; ++k) { //将m[i][j]垂直下方的元素都变成0
double t = m[k][j] / m[i][j];
m[k][j] = 0;
for (int l = j + 1; l <= n + 1; ++l) {
m[k][l] -= t * m[i][l];
}
}
i++, j++;
}
for (int k = i + 1; k <= n; ++k) {
if (fabs(m[k][n + 1]) > eps) return false; //出现非法情况
}
if (i != n + 1) return false; //不满秩,则有无穷多解
for (int k = n; k >= 1; --k) { //不断回带求解
double t = m[k][n + 1];
for (int l = k + 1; l <= n; ++l) {
t -= m[k][l] * x[l];
}
x[k] = t / m[k][k];
}
return true;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n + 1; ++j) {
scanf("%lf", &m[i][j]);
}
}
if (!gauss(n)) {
puts("No Solution");
}
else {
for (int i = 1; i <= n; ++i) {
printf("%.2f\n", x[i]);
}
}
}