高斯约旦消元模版

模版,留个代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn = 110;
constexpr int maxm = 210;
constexpr double eps = 1e-7;

double mat[maxn][maxm];

signed main()
{
    #ifndef ONLINE_JUDGE
    freopen("cjdl.in","r",stdin);
    freopen("cjdl.out","w",stdout);
    #endif // ONLINE_JUDGE

    int n;
    scanf("%lld",&n);
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=n+1;++j)
        {
            scanf("%lf",&mat[i][j]);
        }
        mat[i][i+n+1]=1;// 加入单位矩阵
    }

    int row=1;
    for(int i=1;i<=n;++i)
    {
        int mai=row;
        for(int k=mai+1;k<=n;++k)
        {
            if(fabs(mat[mai][i])<fabs(mat[k][i]))// 选取绝对值最大的点
            {
                mai=k;
            }
        }
        if(fabs(mat[mai][i])<=eps)// 如果当前列最大值小于0,暂时跳过,后面判断是无解还是无穷解
        {
            continue;
        }
        if(mai!=row)
        {
            swap(mat[mai],mat[row]);// 现在row是最大的行
        }

        for(int k=1;k<=n;++k)// 枚举行
        {
            if(k==row)// 跳过自己
            {
                continue;
            }
            double ki=mat[k][i]/mat[row][i];// 比例
            for(int j=i;j<=2*n+1;++j)
            {
                mat[k][j]-=mat[row][j]*ki;
            }
        }
        ++row;
        
        int ki=1/mat[row][i];
        for(int j=i;j<=2*n+1;++j)// 正则化
        {
            mat[row][j]*=ki;
        }
    }

    if(row<=n)// row最后应该是n+1
    {
        for(int i=row;i<=n;++i)// 剩下的行为0
        {
            if(fabs(mat[i][n+1])>eps)// 如果0对应了一个数,无解
            {
                printf("-1\n");
                return 0;
            }
        }
        printf("0\n");
    }
    else
    {
        for(int i=1;i<=n;++i)
        {
            printf("x%lld=%.2lf\n",i,mat[i][n+1]);
            // mat[i][n+1]/mat[i][i] 如果不加单位矩阵进行正则化
        }
    }

    return 0;
}
posted @ 2025-11-23 10:18  玖玮  阅读(5)  评论(0)    收藏  举报