注意事项:
-
高斯消元代码的 14 行和 17~20 行也可向矩阵行列式那样包装成一个函数并使用 bottomj
优化常数。但因为在 Luogu P2455 [SDOI2006]线性方程组 的测试中对常数的优化不明显,又因为 swap(a[row], a[maxer])
在高消中只出现一次,这样做也不会是代码结构更清晰,所以不推荐这种写法。
-
该高斯消元代码只适用于矩阵行列长度相等,适用于行列长度不相等的版本请见异或高斯消元。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| int n; double a[MAXn + 10][MAXn + 10]; int guass() { int row = 1; for (int col = 1; col <= n; ++col) { double mx = 0; int maxer = -1; for (int i = row; i <= n; ++i) { if (mx < abs(a[i][col])) { mx = abs(a[i][col]); maxer = i; } } if (sig(mx) == 0) continue; if (maxer != row) swap(a[row], a[maxer]); for (int i = 1; i <= n; ++i) { if (i == row) continue; double k = a[i][col] / a[row][col]; for (int j = col; j <= n + 1; ++j) { a[i][j] -= a[row][j] * k; } } ++row; } bool noans = 0, infans = 0; if (row <= n) { for (int i = row; i <= n; ++i) { if (sig(a[i][n + 1])) { noans = 1; break; } } if (noans == 0) infans = 1; } if (noans) return 0; else if (infans) return -1; else { for (int i = 1; i <= n; ++i) { a[i][n + 1] /= a[i][i]; a[i][i] = 1; } return 1; } }
|
Luogu P2455 [SDOI2006]线性方程组
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include<bits/stdc++.h> using namespace std; const int MAXn = 50; const double EPS = 1e-8;
template <typename T> inline void read(T &a) { char c;for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar());bool f = c == '-';T x = f ? 0 : (c ^ '0');for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) {x = x * 10 + (c ^ '0');}a = f ? -x : x; } template <typename T, typename ...Argv> inline void read(T &a, Argv &...argv) { read(a), read(argv...); }
inline int sig(double x) { if (x < -EPS) return -1; else if (x > EPS) return 1; else return 0; }
int n; double a[MAXn + 10][MAXn + 10]; int guass() { int row = 1; for (int col = 1; col <= n; ++col) { double mx = 0; int maxer = -1; for (int i = row; i <= n; ++i) { if (mx < abs(a[i][col])) { mx = abs(a[i][col]); maxer = i; } } if (sig(mx) == 0) continue; if (maxer != row) swap(a[row], a[maxer]); for (int i = 1; i <= n; ++i) { if (i == row) continue; double k = a[i][col] / a[row][col]; for (int j = col; j <= n + 1; ++j) { a[i][j] -= a[row][j] * k; } } ++row; } bool noans = 0, infans = 0; if (row <= n) { for (int i = row; i <= n; ++i) { if (sig(a[i][n + 1])) { noans = 1; break; } } if (noans == 0) infans = 1; } if (noans) return 0; else if (infans) return -1; else { for (int i = 1; i <= n; ++i) { a[i][n + 1] /= a[i][i]; a[i][i] = 1; } return 1; } }
signed main() { read(n); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n + 1; ++j) { scanf("%lf", &a[i][j]); } } int res = guass(); if (res == 0) puts("-1"); else if (res == -1) puts("0"); else { for (int i = 1; i <= n; ++i) { printf("x%d=%.2lf\n", i, a[i][n + 1]); } } return 0; }
|