题意

题目描述

给定一个线性方程组,对其求解

输入输出格式

输入格式:

第一行,一个正整数\(n\)

第二至\(n+1\)行,每行\(n+1\)个整数,为\(a_1, a_2 \cdots a_n\)和\(b\),代表一组方程。

输出格式:

共n行,每行一个数,第\(i\)行为\(x_i\)(保留2位小数)

如果不存在唯一解,在第一行输出"No Solution".

输入输出样例

输入样例#1:

3

1 3 4 5

1 4 7 3

9 3 2 2

输出样例#1:

-0.97

5.18

-2.39

说明

\(1 \leq n \leq 100, \left | a_i \right| \leq {10}^4 , \left |b \right| \leq {10}^4\)

分析

参照_皎月半洒花的题解。

emmmm这个消元方式其实严格来说是可行性算法……而不是优化性算法……不过话说由于我太蒟蒻了,所以并不知道什么更优的算法(#滑稽)

嗯,其实这个算法是\(O(n^3)\)的算法,需要一些矩阵及行列式的知识……那么由本蒟蒻来记录一下这个算法吧!

那么假设有一个线性方程组是长这样的:

\[\begin{Bmatrix} 3x & + & 2y &+& z &=&10 \\5x & + & y &+& 6z &=&25 \\2x & + & 3y &+& 4z &=&20\end{Bmatrix}
\]

emmm这就是一个很简单的三元一次方程,让我们想想常规方法该怎么做(先不谈code)

初中老师说过:我们可以加减消元或者代入消元,但是我们需要在程序里实现的时候,需要一种有规律可循的算法。所以我们选择加减消元,但用代入消元回带。

整体思路就是我们可以先在某一个式子里,用这个式子的\(x\)消去其他式子里的\(x\),然后在剩下的两个式子里再选择一个式子里的\(y\),用这个\(y\)消去最后剩下的式子里的\(y\)。那么现在最后一个方程里就只有一个未知数\(z\)了。倘若\(z\)的系数是1,那么我们就可以直接得出答案来了(别觉得这句话是废话)。

比如刚才这个方程,我们用第二个式子去消1、3式里的$x:

\[\begin{Bmatrix} 0\times x & + & \frac{7}{5}y &+& (-\frac{13}{5}z) &=&-5 \\5x & + & y &+& 6z &=&25 \\0\times x & + & \frac{13}{5}y &+& \frac{8}{5}z &=&10\end{Bmatrix}
\]

整理之后再用第三个式子里的\(y\)消去第一个式子里的\(y\)(注意,由于第二个式子作为消元用式,所以接下来的运算不再考虑二式):

\[\begin{Bmatrix}0\times y &+& (-\frac{225}{65}z) &=&-\frac{135}{13} \\ \frac{13}{5}y &+& \frac{8}{5}z &=&10\end{Bmatrix}
\]

那么我们发现在1式中只剩下一个未知数了,那么就可解得:

\(z=3\)

带回三式里解出

\(y=2\)

再将\(x\)、\(y\)带回最早被消掉的二式里,解得

\(x=1\)

好像这个方法再数学逻辑上讲是特别麻烦的,但是却是一个通用性强的方法qwq

那么放在程序实现上来讲,我们可以先用一个n \times (n+1)n×(n+1)的矩阵来记录每一个式子的系数以及结果。譬如上式就可以用矩阵表示成这样:

\[\begin{Bmatrix} 3& 2 & 1 &|& 10 \\5 & 1 & 6 &|& 25 \\2 & 3 & 4 &|&20\end{Bmatrix}
\]

左边记录系数,右边记录每个式子的结果。

那么首先我们需要用第一列中(所有的\(x\)中)系数最大的来消其他两个式子。而这里为了方便起见,我们将这个选中的系数置为1,方便上例中地不断带回原式的操作(这样在回带的时候就可以不考虑原本的系数了)。

由于最多也只能用double型存储,所以必然会有精度误差。但如果我们每次都选用最大系数的来消掉其他系数,就可以最大程度地来减小误差。以下是一种不严谨地、适合意会的证明(选读):

假设我们现在在处理第nn个未知数,此时在众多的未知数nn中,他们的系数分别是\(k_1 k_2 k_3 k_ 4\dots k_m\),那么考虑,在选完\(k_i\)之后,下面我们要进行的是把\(k_i\)消成1。那么此时对于第ii行的其他的系数以及结果我们都要除以\(k_i\) 。

之后呢?之后我们要进行的操作是用这个式子来消掉其他式子里的该未知数啊qwq。如果要这么操作肯定会让其他式子别的未知数的系数,减去当前式子的别的未知数的系数乘上某个值(事实上假设选择含\(k_i\)的式子,则对于每个式子\(j\)而言,每个系数减去当前系数的倍数,这个倍数应该为\(k_j\)那么这样看来,对于当次用来消元的式子的每个系数\(q_{i1}q_{i2}q_{i3}q_{i4} ……q_{iw}\) (假设当前元的系数是\(q_{i1}\)而言,对于每一个其他式子的该项系数\(q_{jw}\),都需要让\(q_{jw}\)变成

\[q_{jw}-\frac{q_{j1}}{q_{i1}} \times q_{iw}
\]

那么我们观察这个式子,\(q_{i1}\)越大,\(\frac{q_{j1}}{q_{i1}}\)期望越小,那么我们考虑,这个值越小,我们就约可以把它看作一个“基本单位”。从而我们就使得减出来的值失精程度越低,最后即可保证数据是从期望上来讲最精确。

嗯,讲的很麻烦,大家挑重点看吧(或者只看最后一个自然段)

在置为1之后,我们需要来用这个式子去消其他的式子(别忘了每个式子的结果也要消)。那么在最后,我们只需要将这个矩阵的最右下角(也就是最后一个元的实际值)不断回带即可。

时间复杂度\(O(n^3)\)

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x){
return x=read<T>();
}
typedef long long ll;
co double eps=1e-7;
double map[111][111],ans[111];
int main(){
// freopen(".in","r",stdin),freopen(".out","w",stdout);
int n=read<int>();
for(int i=1;i<=n;++i)
for(int j=1;j<=n+1;++j) read(map[i][j]);
for(int i=1;i<=n;++i){
int r=i;
for(int j=i+1;j<=n;++j)
if(fabs(map[r][i])<fabs(map[j][i])) r=j;
if(fabs(map[r][i])<eps){
puts("No Solution");
return 0;
}
if(i!=r) std::swap(map[i],map[r]);
double div=map[i][i];
for(int j=i;j<=n+1;++j) map[i][j]/=div;
for(int j=i+1;j<=n;++j){
div=map[j][i];
for(int k=i;k<=n+1;++k) map[j][k]-=map[i][k]*div;
}
}
ans[n]=map[n][n+1];
for(int i=n-1;i>=1;--i){
ans[i]=map[i][n+1];
for(int j=i+1;j<=n;++j) ans[i]-=(map[i][j]*ans[j]);
}
for(int i=1;i<=n;++i) printf("%.2lf\n",ans[i]);
return 0;
}

LG3389 【模板】高斯消元法的更多相关文章

  1. LG3389 「模板」高斯消元法 高斯消元

    问题描述 LG3389 题解 高斯消元,是用来解\(n\)元一次方程组的算法,时间复杂度\(O(n^3)\) 这样就构造出了这个方程组的矩阵 目标就是把这个矩阵左边\(n \times n\)消为单位 ...

  2. 高斯消元法(Gauss Elimination)【超详解&模板】

    高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵.高斯消元法的原理是:若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组. ...

  3. 洛谷P3389 【模板】高斯消元法

    P3389 [模板]高斯消元法 题目背景 Gauss消元 题目描述 给定一个线性方程组,对其求解 输入输出格式 输入格式: 第一行,一个正整数 n 第二至 n+1行,每行 n+1 个整数,为a1​,a ...

  4. 题解 P3389 【【模板】高斯消元法】

    题解 P3389 [[模板]高斯消元法] 看到大家都没有重载运算符,那我就重载一下运算符给大家娱乐一下 我使用的是高斯-约旦消元法,这种方法是精度最高的(相对地) 一句话解释高斯约旦消元法: 通过加减 ...

  5. 「LuoguP3389」【模板】高斯消元法

    题目背景 Gauss消元 题目描述 给定一个线性方程组,对其求解 输入输出格式 输入格式: 第一行,一个正整数 nn 第二至 n+1n+1行,每行 n+1n+1 个整数,为a_1, a_2 \cdot ...

  6. 洛谷——P3389 【模板】高斯消元法

    P3389 [模板]高斯消元法 以下内容都可省略,直接转大佬博客%%% 高斯消元总结 只会背板子的蒟蒻,高斯消元是什么,不知道诶,看到大佬们都会了这个水题,蒟蒻只好也来切一切 高斯消元最大用途就是解多 ...

  7. (模板)poj2947(高斯消元法解同余方程组)

    题目链接:https://vjudge.net/problem/POJ-2947 题意:转换题意后就是已知m个同余方程,求n个变量. 思路: 值得学习的是这个模板里消元用到lcm的那一块.注意题目输出 ...

  8. (模板)poj1681 高斯消元法求异或方程组(无解、唯一解、多解)

    题目链接:https://vjudge.net/problem/POJ-1681 题意:类似于poj1222,有n×n的01矩阵,翻转一个点会翻转其上下左右包括自己的点,求最少翻转多少点能使得矩阵全0 ...

  9. [Luogu 3389]【模板】高斯消元法

    Description 给定一个线性方程组,对其求解 Input 第一行,一个正整数 n 第二至 n+1 行,每行 n+1 个整数,为a1,a2⋯an和 b,代表一组方程.1​​,a​2​​⋯a​n​ ...

随机推荐

  1. uva10817 dijkstra

    大白书P330 #include <iostream> #include <cstdio> #include <algorithm> #include <st ...

  2. Python ConfigParser的使用

    1.基本的读取配置文件 -read(filename) 直接读取ini文件内容 -sections() 得到所有的section,并以列表的形式返回 -options(section) 得到该sect ...

  3. laravel + html ajax 多表单字段和图片一起上传

    $("#article_push").on('click', function (e){ e.preventDefault(); var stylestr = $('#summer ...

  4. Flex开发框架cairngorm入门实例

    Cairngorm是flex开发的mvc框架,现在在 adobe旗下.它架构和eclipse插件开发gef架构很相似,具体工作原理如下: 该框架就是一个Cairngorm.swc文件,大家可以到Cai ...

  5. bzoj3629 / P4397 [JLOI2014]聪明的燕姿

    P4397 [JLOI2014]聪明的燕姿 根据唯一分解定理 $n=q_{1}^{p_{1}}*q_{2}^{p_{2}}*q_{3}^{p_{3}}*......*q_{m}^{p_{m}}$ 而$ ...

  6. 在JAVA可移植性的来源的三方面

    软件可移植性的概念是与软件从某一环境转移到另一环境下的难易程度.为获得较高的可移植性,在设计过程中常采用通用的程序设计语言和运行支撑环境.尽量不用与系统的底层相关性强的语言.下面介绍JAVA的可移植性 ...

  7. 【安装】Nginx安装

    系统平台:CentOS release 6.5 (Final) 64位. 安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtool ...

  8. P4factory ReadMe Quickstart 安装p4factory

    操作系统: Ubuntu 14.04 前言 在之前,我直接从P4.org给的GitHub网址上下载了p4factory,但是在根据ReadMe的内容进行QuickStart的时候,发生了shell脚本 ...

  9. POJ 1159 Palindrome(最长公共子序列)

    http://poj.org/problem?id=1159 题意: 给出一个字符串,计算最少要插入多少个字符可以使得该串变为回文串. 思路: 计算出最长公共子序列,再用原长-LCS=所要添加的字符数 ...

  10. Codeforces Round #319 (Div. 2) C. Vasya and Petya's Game 数学

    C. Vasya and Petya's Game time limit per test 1 second memory limit per test 256 megabytes input sta ...