模板--高斯消元
原题传送门
$A×X=B$,已知矩阵$A$,$B$,求矩阵$X$。
算法流程:
- 把A消成上三角矩阵
依次反代得到结果
消成上三角矩阵过程:
- 初始i=1
- 在未选过行中找到$X_i$项系数绝对值最大的一行,放到第i行。
- 如果它的$X_i$项系数为0,则无解/无穷解,直接返回无解。
- 然后把该行所有系数和结果全部除以$X_i$项系数,$X_i$项系数消成1
- 把其他行的每个数减去第i行对应数$×$这一行$X_i$的系数。
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; }