高斯消元学习笔记

高斯消元

默认大家都学过线代了

算法思想

  1. 就是求解矩阵的过程。把矩阵转化成一个上三角或者下三角的形式,那么只需要把对角线上的元素相乘就可以 O ( n ) O(n) O(n) 得到矩阵的值。

  2. 如何把矩阵转化成上三角或下三角呢,线性代数告诉我们把第i行的每个元素加上第j行对应的每个元素的k倍,原矩阵大小不变。(同理可以消除列)

  3. 判断解的情况:

    a) 如果出现某一行,系数矩阵全为0,增广矩阵不全为0,则无解(即出现[0 0 0 0 0 b],其中b不等于0的情况)(转化为方程就是说 0 × x 1 + . . . + 0 × x n = b ( b ≠ 0 ) 0 \times x_1 + ...+0 \times x_n = b(b \neq 0) 0×x1+...+0×xn=b(b=0) ,显然这不可能);

    b) 如果是严格上三角,则表明有唯一解;

    ​ 形如下图,以对角线为线,左下角全为0或右上角

    ​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cb2IwFV9-1670482002823)(https://tse1-mm.cn.bing.net/th/id/R-C.d85ea5d58289c8b027ec7dd7dbb8ec26?rik=CmoIe2fedyOvCQ&riu=http%3a%2f%2fc.biancheng.net%2fuploads%2fallimg%2f190426%2f1KJR1D-5.gif&ehk=VYbXtHCtR86m65HblKk1JWB5G5OO%2bnEn8uOO1nsW7AM%3d&risl=&pid=ImgRaw&r=0&sres=1&sresct=1)]

    ​ c) 如果增广矩阵有k (k > 0)行全为0(全为0指b也等于0),那么表明有k个变量可以任 意取值,这几个变量即自由变量;对于这种情况,一般解的范围是给定的,令解的取值 有T个,自由变量有V个,那么解的个数就是 TV。

ACWING的基础模板题(防止没买基础课的看不了,题目也加上了)

  • 883. 高斯消元解线性方程组 - AcWing题库

    • 题目:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SI14vpel-1670482002824)(https://s6.jpg.cm/2021/11/15/Iit3LE.png)]

    • 代码+板子

      #include <iostream>
      #include <algorithm>
      #include <cmath>
      
      using namespace std;
      
      const int N = 110;
      const double eps = 1e-6;
      
      int n;
      double a[N][N];
      
      
      int gauss()
      {
          int c, r;
          for (c = 0, 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;
      
              for (int i = c; i < n + 1; i ++ ) swap(a[t][i], a[r][i]);
              for (int i = n; i >= c; i -- ) a[r][i] /= a[r][c];
      
              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[r][j] * a[i][c];
      
              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 -- )
              for (int j = i + 1; j < n; j ++ )
                  a[i][n] -= a[j][n] * a[i][j];
      
          return 0;
      }
      
      int main()
      {
          cin >> n;
          for (int i = 0; i < n; i ++ )
              for (int j = 0; j < n + 1; j ++ )
                  cin >> a[i][j];
      
          int t = gauss();
      
          if (t == 0)
          {
              for (int i = 0; i < n; i ++ ) printf("%.2lf\n", a[i][n]);
          }
          else if (t == 1) puts("Infinite group solutions");
          else puts("No solution");
      
          return 0;
      }
      
      
      
  • 884. 高斯消元解异或线性方程组 - AcWing题库

    • 题目:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tYEKWrkQ-1670482002824)(https://s6.jpg.cm/2021/11/15/IitCbQ.png)]

    • 板子+代码

      #include <iostream>
      #include <algorithm>
      
      using namespace std;
      
      const int N = 110;
      
      
      int n;
      int a[N][N];
      
      
      int gauss()
      {
          int c, r;
          for (c = 0, r = 0; c < n; c ++ )
          {
              int t = r;
              for (int i = r; i < n; i ++ )
                  if (a[i][c])
                      t = i;
      
              if (!a[t][c]) continue;
      
              for (int i = c; i <= n; i ++ ) swap(a[r][i], a[t][i]);
              for (int i = r + 1; i < n; i ++ )
                  if (a[i][c])
                      for (int j = n; j >= c; j -- )
                          a[i][j] ^= a[r][j];
      
              r ++ ;
          }
      
          if (r < n)
          {
              for (int i = r; i < n; i ++ )
                  if (a[i][n])
                      return 2;
              return 1;
          }
      
          for (int i = n - 1; i >= 0; i -- )
              for (int j = i + 1; j < n; j ++ )
                  a[i][n] ^= a[i][j] * a[j][n];
      
          return 0;
      }
      
      
      int main()
      {
          cin >> n;
      
          for (int i = 0; i < n; i ++ )
              for (int j = 0; j < n + 1; j ++ )
                  cin >> a[i][j];
      
          int t = gauss();
      
          if (t == 0)
          {
              for (int i = 0; i < n; i ++ ) cout << a[i][n] << endl;
          }
          else if (t == 1) puts("Multiple sets of solutions");
          else puts("No solution");
      
          return 0;
      

    }

    
    
    
    
    
    
    

题型分类

  • 浮点数消元

    系数矩阵为整数或浮点数,消元的时候乘上的系数为浮点数,一般用于求解浮点数解

  • 整数消元

    系数矩阵全为整数,消元的时候乘上的系数均为整数,整个消元过程不出现浮点数。由于乘法很容易溢出,一般很少用。(真迫不得已就上Java,Python)

  • 模线性方程组(很有用)

    系数矩阵全为整数,消元的时候乘上的系数均为整数,每次运算都模上一个数P,整个消元过程不出现除法。(因为高斯消元的过程和最后的计算都是只有±×,对取模后的结果都没影响,这样算出来的结果和原来答案取模后是一样的

    • 有的是给定解的范围求解的数量,例如:PKU 1830、HDU 3364
    • 有的是求一个解,例如PKU 2065、HDU 3571
    • 有的是求解的存在性,例如PKU1288、PKU 3185。
    • 有的是已知解得绝对值求正负,例如2021icpc济南J
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值