P2455 [SDOI2006]线性方程组(real gauss)

P2455 [SDOI2006]线性方程组

(upd 2018.11.08: 这才是真正的高斯消元模板)

找到所消未知数(设为x)系数最大的式子,把它提上来

把这个式子的 x 系数约成1

把这个式子用来把其他式子的x消掉

重复直到只剩一个未知数,然后往回带

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
typedef double db;
db fabs(db a){return a<0?-a:a;}
const db eps=1e-7;
#define N 103
db a[N][N],sol[N];int n,k1,k2;
void check(){
    for(int i=1,j;i<=n;++i){
        for(j=1;fabs(a[i][j])<eps&&j<=n+1;++j);
        if(j>n+1) k2=1;
        if(j==n+1) k1=1;
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n+1;++j)
            scanf("%lf",&a[i][j]);
    for(int i=1,x;i<=n;++i){
        x=i;
        for(int j=i+1;j<=n;++j)
            if(fabs(a[j][i])>fabs(a[x][i])) x=j;
        if(x!=i) swap(a[i],a[x]);
        if(fabs(a[i][i])<eps) continue;
        for(int j=1;j<=n;++j){
            if(i==j) continue;
            db div=a[j][i]/a[i][i];
            for(int u=i;u<=n+1;++u)
                a[j][u]-=a[i][u]*div;//
        }
    }check();
    if(k1){printf("-1");return 0;}//判断无解要在无穷解前面
    if(k2){printf("0");return 0;}
    for(int i=n;i;--i){
        sol[i]=a[i][n+1];
        for(int j=n;j>i;--j)
            sol[i]-=a[i][j]*sol[j];
        sol[i]/=a[i][i];
    }
    for(int i=1;i<=n;++i){
        printf("x%d=%.2lf\n",i,sol[i]+eps);//防止-0.00出现
    }return 0;
}

 

posted @ 2018-09-13 13:56  kafuuchino  阅读(278)  评论(0编辑  收藏  举报