首页 > 其他分享 >高斯消元

高斯消元

时间:2024-02-03 23:44:45浏览次数:33  
标签:当前 int 主元 MaxN 等式 高斯消

高斯消元

板题 [SDOI2006] 线性方程组(别问我为什么不是【模板】高斯消元法,这个太**了)

思路

首先需要引入一个定义增广矩阵

所以一个 \(n\) 元线性方程组就可以抽象成一个矩阵,\(a\) 为系数,\(b\) 为方程的常数项:

\(\begin{bmatrix}a_{11}&\cdots&a_{1n}&b_{1}\\\vdots&\ddots&\vdots\\a_{n1}&\cdots&a_{nn}&b{n}\end{bmatrix}\)

我们知道对于任意一个一元一次方程,我们都需要将其解成一个类似于 \(ax=b\) 的形式,然后变成 \(x=\frac{b}{a}\),所以对于一个方程组,其实是一样的也需要解成一堆七七八八的东西,然后将 \(a\) 变成一个单位矩阵,此时右边的 \(b\) 就是对应行的主元的解了。

为了达成这个目标,我们有三种行变换操作,目的是为了在保证主元解不变的情况下进行变化:

  1. 交换两行,这个很显然不会变答案
  2. 将一行整体缩放一个数,这个很显然可以用等式的性质二来证明(欸,要证明吗,好像本来就满足)
  3. 将一行叠加到另一行去,这个可以用等式的性质一来证明(嘿,好像不用证明)

好,此时我们就可以快速口胡一份代码了,我们可以对于每一行都将其下面的全部都变成 \(0\),因为动了上面的,那么上面的也得行变换,下面的也都得行变换了,注意此时是要用行变换的!!!做完以后就发现最后一行刚好是一个 \(a_{nn}=b_n\) 的东西,所以可以将 \(x_n\) 求出,然后倒着带入求解其它的元即可。

到这里,我们就解决完了所有等式有唯一解的情况了,接下来就要说一些特殊的情况:

  1. 等式当前行主元系数为 \(0\),这个又分两种情况,一个呢是下面的当前主元系数不为 \(0\),那么此时只要用行变换把它弄上来即可,至于为什么不动上面的,理由和上面一样,二个呢是下面的当前主元系数也为 \(0\),那么这个主元,就变成了无论是什么,整个式子都成立,所以就成了无唯一解,可此时我们还不能下定结论,因为下面还有更离谱的事情,不过这就告诉我们,我们不能单纯的只维护当前行,应该把当前列也维护了,因为如果当前行的当前主元无唯一解时,我们就需要让当前列往后走,找到一个有唯一解的主元给当前行,那么跑到最后时,当前行和当前列不一定都跑完了所有的方程。
  2. 等式接完后有剩余等式,这个时候我们会发现一件事情,就是这些等式与上面的等式是线性相关的,所以解不解都没关系,但是,这里因为已经被上面削成了 \(0\),所以有可能会出现 \(0\ne 0\) 的情况,所以要判无解,然后再判无唯一解。

好,到这里就全算完了。

code

#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;

const int MaxN = 110;
const double eps = 1e-4;

double a[MaxN][MaxN], ans[MaxN];
int n;

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n + 1; j++) {
      cin >> a[i][j];
    }
  }
  int i, j;
  for (i = 1, j = 1; i <= n && j <= n;) {
    int u = 0;
    for (int k = n; k >= i; k--) {
      if (fabs(a[k][j]) > eps) {
        u = k;
      }
    }
    if (!u) {
      j++;
      continue;
    } 
    for (int k = 1; k <= n + 1; k++) {
      swap(a[i][k], a[u][k]);
    }
    for (int k = i + 1; k <= n; k++) {
      double d = a[k][j] / a[i][j];
      for (int l = j; l <= n + 1; l++) {
        a[k][l] -= a[i][l] * d;
      }
    }
    i++, j++;
  }
  for (int k = i; k <= n; k++) {
    if (fabs(a[k][n + 1]) > eps) {
      cout << "-1" << endl;
      return 0;
    }
  }
  if (j < n || i < n) {
    cout << "0" << endl;
    return 0;
  }
  for (int i = n; i >= 1; i--) {
    double sum = 0;
    for (int j = 1; j <= n; j++) {
      sum += ans[j] * a[i][j];
    }
    if (fabs(a[i][i]) < eps) {
      cout << "0" << endl;
      return 0;
    }
    ans[i] = (a[i][n + 1] - sum) / a[i][i];
  }
  for (int i = 1; i <= n; i++) {
    cout << fixed << setprecision(2) << "x" << i << "=" << ans[i] << endl;
  }
  return 0;
}

标签:当前,int,主元,MaxN,等式,高斯消
From: https://www.cnblogs.com/ybtarr/p/18005407

相关文章

  • 高斯消元法
    高斯消元高斯消元是线性代数规划中的一个算法,可用来为线性方程组求解,高斯消元法可以用在电脑中来解决数千条等式及未知数。ps:若要解出\(n\)个未知数的话,则需要\(n\)个有意义的方程。例如有\(n\)个方程组,其中一个是\(0\timesx=0\timesy\)你会发现无论\(x\)和\(......
  • P3389 【模板】高斯消元法
    #include<bits/stdc++.h>usingnamespacestd;doublemax(doublea,doubleb){ if(a>=b)returna; if(a<b)returnb;}intn;doublea[1010][1010];doublea1[1010][1010];intmain(){ scanf("%d",&n); for(inti=1;i<=n;i++) { ......
  • 一次线性方程组 高斯消元笔记
    高斯消元原理高斯消元用来解如下形式的方程组:\[\begin{cases}a_{1,1}x_1+a_{1,2}x_2+\cdots+a_{1,n}x_n=b_1\\a_{2,1}x_1+a_{2,2}x_2+\cdots+a_{2,n}x_n=b_2\\\cdots\\a_{n,1}x_1+a_{n,2}x_2+\cdots+a_{n,n}x_n=b_n\end{cases......
  • 高斯消元
    高斯消元设有n个未知数m个方程的线性方程组\[\begin{cases}a_{11}x_{1}+a_{12}x_{2}+\dots+a_{1n}x{n}=b_{1}\\a_{21}x_{1}+a_{22}x_{2}+\dots+a_{2n}x{n}=b_2\\\dots\dots\\a_{m1}x_1+a_{m2}x_{2}+\dots+a_{mn}x_{n}=b_m\end{cases}\]其中\(a_{ij}\)是第i个方程的第......
  • 高斯消元
    作用解线性方程组,将其系数和常数放在矩阵中,利用加减消元,得到一个倒三角,反着代入计算即可。double型可以选最大的一行交换,减少误差。异或型可以bitset优化,加减变^,乘除变&。稀疏矩阵可以手动代入消元,减少计算量。Link......
  • 2023.11.8 高斯消元记录
    2021ICPC沈阳I题https://link.zhihu.com/?target=https%3A//ac.nowcoder.com/acm/contest/24346/I2020ICPC济南A题https://ac.nowcoder.com/acm/contest/10662/A高斯消元只要构造出增广矩阵,求解就很简单了.对本题来说,矩阵乘开后,新矩阵的列向量,就是B*C的列向量.......
  • 高斯消元
    问题求解线性方程组算法思想高斯消元法的实现主要分为两种,一种是普通的高斯消元,将系数矩阵消为上三角矩阵,再一步步回代求出所有未知数;第二种是高斯-约旦消元法,将系数矩阵消为对角矩阵,不需要回代即可直接解出未知数,这里展示第二种做法。代码实现例题:P3389【模板】高斯消元法......
  • 浅谈高斯消元法
    2023.6.16:发布2023.8.29:修缮,加上自己觉得通俗易懂的理解,更新矩阵求逆。高斯消元高斯消元可以用于线性方程组求解或者行列式计算,求矩阵的逆等等,也算是比较基础的一个思想。消元法定义消元法是将方程组中的一方程的未知数用含有另一未知数的代数式表示,并将其带入到另一方程中,......
  • 【学习笔记】简单数论-高斯消元与线性空间
    友情提示本博客内部分内容因缺乏样例,可能晦涩难懂,建议参考蓝书或者数论小白都能看懂的线性方程组及其解法。线性方程组线性方程组是由\(M\)个\(N\)元一次方程共同构成的。线性方程组的所有系数可以写成一个\(M\)行\(N\)列的系数矩阵,再加上每个方程等号右侧的常数,可......
  • 高斯消去法python代码
    高斯消去法实现多元线性方程组求解1.流程概述高斯消去法(GaussianElimination)是一种用于求解多元线性方程组的常用方法。它通过将方程组表示为增广矩阵的形式,然后进行一系列的行变换,将增广矩阵转化为上三角矩阵,最后利用回代法求解方程组。以下是高斯消去法的流程:步骤操作......