原题传送门
$A×X=B$,已知矩阵$A$,$B$,求矩阵$X$。
算法流程:

  1. 把A消成上三角矩阵
  2. 依次反代得到结果

    消成上三角矩阵过程:

  3. 初始i=1
  4. 在未选过行中找到$X_i$项系数绝对值最大的一行,放到第i行。
  5. 如果它的$X_i$项系数为0,则无解/无穷解,直接返回无解。
  6. 然后把该行所有系数和结果全部除以$X_i$项系数,$X_i$项系数消成1
  7. 把其他行的每个数减去第i行对应数$×$这一行$X_i$的系数。
  8. 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;
    }

标签: 数学, 模板

添加新评论