1. 构造增广矩阵
  2. 找到绝对值最大的行
  3. 将绝对值最大的行置于目前第一行
  4. 将第一个数字消为 $1$
  5. 将 $2\sim n$ 行的第一个数字消为 $0$
  6. 合并答案

代码实现

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
int gauss() {
int c, r;
for (c = r = 0; c < n; ++c) { // 枚举列
int t = r;
for (int i = r; i < n; ++i) // 找到绝对值最大的行
if (fabs(a[i][c]) > fabs(a[t][c])) t = i;

if (fabs(a[t][c]) < eps) continue; // 最大为 0,跳过

for (int i = c; i <= n; ++i)
std::swap(a[t][i], a[r][i]);

// 将第一个数置为 0
for (int i = n; i >= c; --i) a[r][i] /= a[r][c];

// 将 a[i][c](第一个数) 置为 0
for (int i = r + 1; i < n; ++i)
if (fabs(a[i][c]) > eps)
for (int j = n; j >= c; --j)
a[i][j] -= a[i][c] * a[r][j];

++r;
}

if (r < n) {
for (int i = r; i < n; ++i)
if (fabs(a[i][n]) > eps) return 2; // 无解
return 1; // 有无穷多组解
}

for (int i = n - 1; i >= 0; --i) // 正在求 x_i
for (int j = i + 1; j < n; ++j)
a[i][n] -= a[i][j] * a[j][n];

return 0; // 有唯一解
}