高斯消元的作用:
求解n个未知数、n个方程的方程组
例如如下n个方程、n个未知数:
写成n*(n+1)的矩阵:
枚举每一列
第一步:找到绝对值最大的一行
第二步:将该行换到最上面
第三步:将该行的第一个数变成1
第四步:将下面行的此列变为0
注意的是,换好了的行不需要动!
举一个例子:
求解有三个方程、三个未知数的方程组:
写成矩阵形式:
枚举第一列,找到最大行:
将该行换到最上面,并将该行第一个数变为1:
将下面行的第1列都变成0:
枚举第二列,找到绝对值最大的一行,将该行的第一个数变成1:
将下面行的第1列都变成0:
遍历第三列(由于第一行和第二行都已经改变好了,不需要动了),这里直接把第三行的第一个数变为1就行了:
最后化简为:
由此可以依次算出:
x3=3;
x2=-2;
x1=3;
例题链接: 883. 高斯消元解线性方程组 - AcWing题库
代码(详细注释):
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
typedef long long ll;
const int N=110;
const double eps=1e-8;
int n;
double a[N][N];
int gauss()// 高斯消元,答案存于a[i][n]中,0 <= i < n
{
int c,r;//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)//最大值为0
continue;
for(int i=c;i<=n;i++) swap(a[t][i],a[r][i]);// 将绝对值最大的行换到最顶端
for(int i=n;i>=c;i--) a[r][i]/=a[r][c];//将当前行的首位变成1
for(int i=r+1;i<n;i++)// 用当前行将下面所有的列消成0
if(fabs(a[i][c])>eps)
for(int j=n;j>=c;j--)
a[i][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[i][n]-a[i][j]*a[j][n];
return 0;
}
int main()
{
IOS;
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==2) cout<<"No solution"<<endl;//无解
else if(t==1) cout<<"Infinite group solutions"<<endl;//多解
else//唯一解
{
for(int i=0;i<n;i++)
{
if(fabs(a[i][n])<eps) a[i][n]=0;//去掉输出-0.00的情况
printf("%.2lf\n", a[i][n]);
}
}
return 0;
}