0
点赞
收藏
分享

微信扫一扫

高斯消元法 思路及模板代码

高斯消元法解线性方程组

思路及步骤

在这里插入图片描述
最后的到一个(近似)阶梯形矩阵
在这里插入图片描述
再把它化简成近似单位矩阵,即可得到解


模板代码

//题目背景:AcWing 883
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=110;
const double eps=1e-8;   //别把double误写成int,之所以要小于1e-8,是因为c++浮点数的一种弊端,所以小于eps时,可以近似的看作是0
double a[N][N];  //存储增广矩阵
int n;
int gauss()
{
    int r,c;  //r表示当前要处理的这一行    
    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;    //如果元素最大,还是0,那就跳过,去处理下一列
        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];    //把这一行的第c列化成1
        for(int i=r+1;i<n;i++)             //把其他行的第c列消成0
            if(fabs(a[i][c])>eps)
            {
                for(int j=n;j>=c;j--)
                    a[i][j]-=a[i][c]*a[r][j];
            }
        r++;
    }
    if(r<n)     //如果最后不是严格完全的阶梯型
    {
        for(int i=r;i<n;i++)
            if(fabs(a[i][n])>eps)      //0==非零的情况,无解
                return 2;
        return 1;        //0==0的情况,有无穷多解
    }
    for(int i=n-1;i>=0;i--)                //从下往上的把解给求出来
        for(int j=i+1;j<n;j++)
            a[i][n]-=a[j][n]*a[i][j];
    return 0;
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        for(int j=0;j<n+1;j++)
            scanf("%lf",&a[i][j]);
    int t=gauss();
    if(t==2)
        printf("No solution");
    else if(t==1)
        printf("Infinite group solutions");
    else
        for(int i=0;i<n;i++)
        {
            if(fabs(a[i][n])<eps)
                a[i][n]=0;
            printf("%.2lf\n",a[i][n]);
        }
    return 0;
}

高斯消元法解异或线性方程组

思路及步骤

与高斯消元法解线性方程组一致
在这里插入图片描述
在这里插入图片描述

模板代码

//题目背景:AcWing 884
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110;
int n;
int 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(a[i][c])    //找到第c列中第一个不为0的行就行了
            {
                t=i;
                break;
            }
        if(!a[t][c]) continue;  //如果全为0了,就continue
        for(int i=c;i<=n;i++) swap(a[r][i],a[t][i]);   //把这一行放到上面去
        for(int i=r+1;i<n;i++)    //用选中的这一行去消下面的行,把第c列消为0
            if(a[i][c])
                for(int j=c;j<=n;j++)
                    a[i][j]^=a[r][j];
        r++;
    }
    if(r<n)
    {
        for(int i=r;i<n;i++)
            if(a[i][n])
                return 2;
        return 1;
    }
    for(int i=n-1;i>=0;i--)
        for(int j=i+1;j<n;j++)
            if(a[i][j])
                a[i][n]^=a[j][n];
    return 0;
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        for(int j=0;j<n+1;j++)
            scanf("%d",&a[i][j]);
    int res=gauss();
    if(res==2)
        printf("No solution");
    else if(res==1)
        printf("Multiple sets of solutions");
    else
        for(int i=0;i<n;i++)
            printf("%d\n",a[i][n]);
    return 0;
}
举报

相关推荐

0 条评论