模板--高斯消元

原题传送门 \(A×X=B\),已知矩阵\(A\),\(B\),求矩阵\(X\)。 算法流程: 1. 把A消成上三角矩阵 2. 依次反代得到结果 消成上三角矩阵过程: 1. 初始i=1 2. 在未选过行中找到\(X_i\)项系数绝对值最大的一行,放到第i行。 3. 如果它的\(X_i\)项系数为0,则无解/无穷解,直接返回无解。 4. 然后把该行所有系数和结果全部除以\(X_i\)项系数,\(X_i\)项系数消成1 5. 把其他行的每个数减去第i行对应数\(×\)这一行\(X_i\)的系数。 6. i=i+1,回到第2步 就可以了。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define up(a,b,c) for (int a(b),end##a(c);a<=end##a;++a)
#define down(a,c,b) for (int a(b),end##a(c);a>=end##a;--a)
#define uup(a,c,b) for (int a(b),end##a(c);a<=end##a;++a)
#define udown(a,b,c) for (int a(b),end##a(c);a>=end##a;--a)
using namespace std;
int read(){
    char s;
    int k=0,base=1;
    while((s=getchar())!='-'&&s!=EOF&&!(s>='0'&&s<='9'));
    if(s==EOF)exit(0);
    if(s=='-')base=-1,s=getchar();
    while(s>='0'&&s<='9'){
        k=k*10+(s-'0');
        s=getchar();
    }
    return k*base;
}
void write(int x){
    if(x<0){
        putchar('-');
        write(-x);
    }
    else{
        if(x/10)write(x/10);
        putchar(x%10+'0');
    }
}
int n;
struct FC{
    double a[128],b;
};
FC fc[233];
void HJ(FC a,FC &b,int c){//用方程a消掉方程b的$X_c$
    up(i,1,n)a.a[i]*=b.a[c];
    a.b*=b.a[c];
    up(i,1,n)b.a[i]-=a.a[i];
    b.b-=a.b;
}
#define abs(a) ((a)<0?-(a):(a))
int main(){
    n=read();
    up(i,1,n){
        up(j,1,n)cin>>fc[i].a[j];
        cin>>fc[i].b;
    }
    up(i,1,n){
        up(j,i+1,n){
            if(abs(fc[j].a[i])>abs(fc[i].a[i])){
                FC t=fc[i];fc[i]=fc[j];fc[j]=t;
            }
        }
        if(fc[i].a[i]==0){
            printf("No Solution\n");
            return 0;
        }
        double s=fc[i].a[i];
        up(j,1,n)fc[i].a[j]/=s;
        fc[i].b/=s;
        up(j,i+1,n)HJ(fc[i],fc[j],i);
    }
    //消成了上三角矩阵
    down(i,1,n){
        double s=fc[i].a[i];
        up(j,1,n)
            fc[i].a[j]/=s;fc[i].b/=s;
        down(j,1,i-1)
            HJ(fc[i],fc[j],i);//反代消元
    }
    up(i,1,n)printf("%.2lf\n",fc[i].b);
    return 0;
}