高斯消元是线性代数中的重要算法,常用于解决线性方程组。也可以用来求矩阵的逆等问题。
咱们先来回顾一下初等行列变换
1.将某一行乘上一个非零数,解不变
2.交换某两行,解不变
3.将某一行的若干倍加到另一行,解不变
算法步骤:
1.枚举每一列,找到绝对值最大的一行
2.将该行和第一行交换
3.将该行行首置为一
4.将下面所有行第 i 列置为零
我们来模拟一个样例:
最后我们就得到了阶梯型矩阵了。
但是还没有结束,最后我们还需要将矩阵倒着减一遍就可以了(也叫回带)
洛谷题:https://www.luogu.com.cn/problem/P3389
上代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
const double eps = 1e-6;
int n;
double a[N][N];
int gauss()
{
int r,c; //行 列
for(r =0,c=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++)//将下面所有行第 c 列置为零
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) return 1;
for(int i=n-1;i>=0;i--)//回带,将答案存在a[i][n]中
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 puts("No Solution");
}
收工。