AcWing算法基础课笔记——高斯消元

2024-06-22 21:12

本文主要是介绍AcWing算法基础课笔记——高斯消元,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

高斯消元

用来求解方程组
a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n = b 1 a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n = b 2 … a n 1 x 1 + a n 2 x 2 + ⋯ + a n n x n = b n 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 \\ a_{n1} x_1 + a_{n2} x_2 + \dots + a_{nn} x_n = b_n\\ a11x1+a12x2++a1nxn=b1a21x1+a22x2++a2nxn=b2an1x1+an2x2++annxn=bn
输入是 n × ( n − 1 ) n \times (n -1 ) n×(n1)的矩阵。

对方程组进行以下三种初等行列变换后,方程的解不变:

  1. 把某一行乘以一个非零的数
  2. 交换某2行
  3. 把某行的若干倍加到另一行上去

因此,对任意一个方程组,可以把它变成倒三角形式:
a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n = b 1 a 22 x 2 + ⋯ + a 2 n x n = b 2 … a ( n − 1 ) ( n − 1 ) x n − 1 + a ( n − 1 ) n x n = b n − 1 a n n x n = b n a_{11}x_1 + a_{12}x_2+\dots +a_{1n}x_n = b_1 \\ a_{22}x_2 + \dots + a_{2n} x_n = b_2 \\ \dots \\ a_{(n-1)(n-1)}x_{n-1} +a_{(n-1)n}x_{n} = b_{n-1}\\ a_{nn}x_n = b_n a11x1+a12x2++a1nxn=b1a22x2++a2nxn=b2a(n1)(n1)xn1+a(n1)nxn=bn1annxn=bn
有三种情况:

  1. 完美阶梯型——唯一解
  2. 0 = 非零 ———无解
  3. 0 = 0 ——无穷多组解

高斯消元步骤:

枚举每一列c:

  1. 找到绝对值最大的一行
  2. 将该行换到最上面
  3. 将该行第一个数变成1
  4. 将下面所有行的第c列消成0

题目

详见:https://www.acwing.com/problem/content/description/885/

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

方程组中的系数为实数。

求解这个方程组。

下图为一个包含 m 个方程 n 个未知数的线性方程组示例:

在这里插入图片描述

输入格式

第一行包含整数 n。

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

输出格式

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

注意:本题有 SPJ,当输出结果为 0.00 时,输出 -0.00 也会判对。在数学中,一般没有正零或负零的概念,所以严格来说应当输出 0.00,但是考虑到本题作为一道模板题,考察点并不在于此,在此处卡住大多同学的代码没有太大意义,故增加 SPJ,对输出 -0.00 的代码也予以判对。

如果给定线性方程组存在无数解,则输出 Infinite group solutions

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

数据范围

1≤n≤100,
所有输入系数以及常数均保留两位小数,绝对值均不超过 100。

输入样例:
3
1.00 2.00 -1.00 -6.00
2.00 1.00 -3.00 -9.00
-1.00 -1.00 2.00 7.00
输出样例:
1.00
-2.00
3.00

代码

#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 ++ ) {// 找到绝对值最大的一行 t 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; //如果第t行为0,结束//将该行换到最上面 for(int i = c; i <= n; i ++ ) swap(a[t][i], a[r][i]);  //将该行的第c位设为1(前面都为0) for(int i = n; i >= c; i --) a[r][i] /= a[r][c];//将下面所有行的第c列消成0//也就是从r + 1行开始,对于第i行,第i行第c个位置a[i][c]如果不为0的话,就要消成0// a[i][c]消成0 : a[i][c] -= a[r][c] * a[i][c]     a[r][c]为1// 那么其他所有列: a[i][j] -= a[r][j] * a[i][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; //有无穷多组解 }//求解唯一解 //从第n - 1 行开始往上,遍历每一行//对于第i行,它的解是a[i][n]的值 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; 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;
}

这篇关于AcWing算法基础课笔记——高斯消元的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1085426

相关文章

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1