题解 P2455 【[SDOI2006]线性方程组】

· · 题解

看到没有题解,那我来发一篇好了

这道题。。。。。数论嘛

高斯消元+增广矩阵的判解

对于用增广矩阵求解,说白了就是带入消元,然后求出最后的那个解,再往前带,求出每个解

看不明白的可以看代码嘛(雾)

注意在化简行也就是消元的时候要找系数最大的那个

求解很简单,判断无解真是醉了,时间用的略长

一定要注意先判-1,再判0,卡了两次。。。。。

还有我有一点看不懂,为什么0的时候不用保留两位小数,也许我太弱看不出来(逃

码风并不优美,大佬们见谅咯

#include<bits/stdc++.h>
#define jd (1e-8)
using namespace std;
double f[100][100];
int n;
double ans[100];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n+1;j++){
            scanf("%lf",&f[i][j]);
        }
    }
    //化简行
    for(int i=1;i<=n;i++){
        int p=i;
        for(int j=i+1;j<=n;j++)if(fabs(f[j][i])>fabs(f[p][i]))p=j;
        for(int j=1;j<=n+1;j++)swap(f[p][j],f[i][j]);
        if(fabs(f[i][i])<jd)continue;
        double num=f[i][i];
        for(int j=1;j<=n+1;j++)f[i][j]/=num;
        for(int j=1;j<=n;j++){
            if(i!=j){
                double numx=f[j][i];
                for(int k=1;k<=n+1;k++)f[j][k]-=f[i][k]*numx;
            }
        }
    }
    //判解
    int opt1=0;
    int opt2=0;
    for(int i=1;i<=n;i++){
        int j=1;
        while(fabs(f[i][j])<jd&&j<=n+1)j++;
        if(j>n+1)opt1=1;
        else if(j==n+1)opt2=1;
    }
    if(opt2){
        printf("-1");
        return 0;
    }
    if(opt1){
        printf("0");
        return 0;
    }
    //化简完了之后往回带,从而求出每个未知数的解
    for(int i=n;i>=1;i--){
        ans[i]=f[i][n+1];
        for(int j=i-1;j>=1;j--){
            f[j][n+1]-=ans[i]*f[j][i];
            f[j][i]=0;
        }
    }
    //输出解
    for(int i=1;i<=n;i++){
        //没办法特判0咯
        if(fabs(ans[i])<jd)printf("x%d=0\n",i);
        else printf("x%d=%.2lf\n",i,ans[i]);
    }
    return 0;
}