高斯消元

一.高斯消元解线性方程组

题目:输入一个增广矩阵,输出所有的解

分析:如果出现 0 = x(>0) 无解, 0 = 0 无穷多解, 完美梯形就是唯一解

代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 
 5 using namespace std;
 6 
 7 const int N = 110;
 8 const double eps = 1e-6;
 9 
10 int n;
11 double a[N][N];
12 
13 
14 int gauss()
15 {
16     int c, r;// c 代表 列 col , r 代表 行 row
17     for (c = 0, r = 0; c < n; c ++ )
18     {
19         int t = r;// 先找到当前这一列,绝对值最大的一个数字所在的行号
20         for (int i = r; i < n; i ++ )
21             if (fabs(a[i][c]) > fabs(a[t][c]))
22                 t = i;
23 
24         if (fabs(a[t][c]) < eps) continue;// 如果当前这一列的最大数都是 0 ,那么所有数都是 0,就没必要去算了,因为它的约束方程,可能在上面几行
25 
26         for (int i = c; i < n + 1; i ++ ) swap(a[t][i], a[r][i]);//// 把当前这一行,换到最上面(不是第一行,是第 r 行)去
27         for (int i = n; i >= c; i -- ) a[r][i] /= a[r][c];// 把当前这一行的第一个数,变成 1, 方程两边同时除以 第一个数,必须要到着算,不然第一个数直接变1,系数就被篡改,后面的数字没法算
28         for (int i = r + 1; i < n; i ++ )// 把当前列下面的所有数,全部消成 0
29             if (fabs(a[i][c]) > eps)// 如果非0 再操作,已经是 0就没必要操作了
30                 for (int j = n; j >= c; j -- )// 从后往前,当前行的每个数字,都减去对应列 * 行首非0的数字,这样就能保证第一个数字是 a[i][0] -= 1*a[i][0];
31                     a[i][j] -= a[r][j] * a[i][c];
32 
33         r ++ ;// 这一行的工作做完,换下一行
34     }
35 
36     if (r < n)// 说明剩下方程的个数是小于 n 的,说明不是唯一解,判断是无解还是无穷多解
37     {// 因为已经是阶梯型,所以 r ~ n-1 的值应该都为 0
38         for (int i = r; i < n; i ++ )// 
39             if (fabs(a[i][n]) > eps)// a[i][n] 代表 b_i ,即 左边=0,右边=b_i,0 != b_i, 所以无解。
40                 return 2;
41         return 1;// 否则, 0 = 0,就是r ~ n-1的方程都是多余方程
42     }
43     // 唯一解 ↓,从下往上回代,得到方程的解
44     for (int i = n - 1; i >= 0; i -- )
45         for (int j = i + 1; j < n; j ++ )
46             a[i][n] -= a[j][n] * a[i][j];//因为只要得到解,所以只用对 b_i 进行操作,中间的值,可以不用操作,因为不用输出
47 
48     return 0;
49 }
50 
51 int main()
52 {
53     cin >> n;
54     for (int i = 0; i < n; i ++ )
55         for (int j = 0; j < n + 1; j ++ )
56             cin >> a[i][j];
57 
58     int t = gauss();
59 
60     if (t == 0)
61     {
62         for (int i = 0; i < n; i ++ ) printf("%.2lf
", a[i][n]);
63     }
64     else if (t == 1) puts("Infinite group solutions");
65     else puts("No solution");
66 
67     return 0;
68 }
View Code

二.高斯消元解异或线性方程组

题目:

输入一个包含n个方程n个未知数的异或线性方程组。

方程组中的系数和常数为0或1,每个未知数的取值也为0或1。

求解这个方程组。

异或线性方程组示例如下:

M[1][1]x[1] ^ M[1][2]x[2] ^ … ^ M[1][n]x[n] = B[1]
M[2][1]x[1] ^ M[2][2]x[2] ^ … ^ M[2][n]x[n] = B[2]
…
M[n][1]x[1] ^ M[n][2]x[2] ^ … ^ M[n][n]x[n] = B[n]

其中“^”表示异或(XOR),M[i][j]表示第i个式子中x[j]的系数,B[i]是第i个方程右端的常数,取值均为0或1。

输入格式

第一行包含整数n。

接下来n行,每行包含n+1个整数0或1,表示一个方程的n个系数以及等号右侧的常数。

输出格式

如果给定线性方程组存在唯一解,则输出共n行,其中第i行输出第i个未知数的解。

如果给定线性方程组存在多组解,则输出“Multiple sets of solutions”。

如果给定线性方程组无解,则输出“No solution”。

数据范围

1n1001≤n≤100

输入样例:

3
1 1 0 1
0 1 1 0
1 0 0 1

输出样例:

1
0
0
 1 #include <iostream>
 2 using namespace std;
 3 
 4 const int N = 110;
 5 int a[N][N];
 6 int n;
 7 
 8 int gauss(){
 9     int c, r;
10     for(c = r = 0;c < n;++c){
11         int t = r;
12         
13         //在当前列找到值为1的
14         for(int i = r;i < n;++i)
15             if(a[i][c])
16                 t = i;
17         if(!a[t][c]) continue;
18         
19         //和r行交换
20         for(int i = c;i <= n;++i) swap(a[r][i], a[t][i]);
21         
22         //当前列消0
23         for(int i = r + 1;i < n;++i)
24             if(a[i][c])
25                 for(int j = n;j >= c;--j)
26                     a[i][j] ^= a[r][j];
27         
28         ++r;
29     }
30     
31     if(r < n){
32         for(int i = r;i < n;++i)
33             if(a[i][n]) return 2;
34         return 1;
35     }
36     //这块就背了
37     for (int i = n - 1; i >= 0; i -- )
38         for (int j = i + 1; j < n; j ++ )
39             a[i][n] ^= a[i][j] * a[j][n];
40     
41     return 0;
42 }
43 
44 int main(){
45     cin >> n;
46 
47     for (int i = 0; i < n; i ++ )
48         for (int j = 0; j < n + 1; j ++ )
49             cin >> a[i][j];
50 
51     int t = gauss();
52 
53     if (t == 0)
54     {
55         for (int i = 0; i < n; i ++ ) cout << a[i][n] << endl;
56     }
57     else if (t == 1) puts("Multiple sets of solutions");
58     else puts("No solution");
59 
60     return 0;
61 }
View Code
原文地址:https://www.cnblogs.com/sxq-study/p/12270129.html