5272: 逆矩阵 ![分享至QQ空间](http://210.32.82.1/acmhome/forum/images/ico_qzone.gif)
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByte
Total Submit: 11 Accepted:7
Total Submit: 11 Accepted:7
Description
设A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩阵B,使得:AB=BA=E(单位矩阵)。 则我们称B是A的逆矩阵,而A则被称为可逆矩阵。
现在告诉你一个n阶方阵A,求它的逆矩阵B。
Input
输入数据有多组,第一行为数据组数T,接下来有T个矩阵。
每个矩阵的第一行为n(n<20),表示n阶方阵,接下来的n行n列表示n*n的矩阵
矩阵元素为实数。
Output
按照n行n列输出逆矩阵B,所有元素保留2位小数。数据保证一定有逆矩阵。
Sample Input
1
5
1.3 0.8 0.5 0.8 1.0
0.5 0.6 1.0 1.3 1.0
0.8 1.4 0.9 1.1 1.4
1.0 0.6 0.8 1.4 0.5
0.7 0.6 1.4 1.4 1.2
Sample Output
0.86 -1.37 -0.36 0.37 0.69
-1.10 -1.90 1.71 0.93 0.12
-1.08 -4.01 0.72 0.64 3.14
0.01 3.06 -0.61 0.33 -1.99
1.29 2.85 -0.77 -1.81 -0.97
Source
矩阵的逆,我提供了两种方法。
LU分解
#include<stdio.h> const int N=21; double a[N][N],b[N][N],c[N][N],bt[N][N],ct[N][N],ans[N][N]; int T,n; void LU() { for(int i=0; i<n; i++) for(int j=0; j<n; j++)b[i][j]=c[i][j]=bt[i][j]=ct[i][j]=ans[i][j]=0; for(int i=0; i<n; i++)b[i][i]=bt[i][i]=1; double s; for(int i=0; i<n; i++) { for(int j=i; j<n; j++) { s=0; for(int k=0; k<i; k++) s+=b[i][k]*c[k][j]; c[i][j]=a[i][j]-s; } for(int j=i+1; j<n; j++) { s=0; for(int k=0; k<i; k++) s+=b[j][k]*c[k][i]; b[j][i]=(a[j][i]-s)/c[i][i]; } } for(int i=1; i<n; i++) for(int j=0; j<i; j++) { s=0; for(int k=0; k<i; k++) s+=b[i][k]*bt[k][j]; bt[i][j]=-s; } for(int i=0; i<n; i++) ct[i][i]=1/c[i][i]; for(int i=1; i<n; i++) for(int j=i-1; j>=0; j--) { s=0; for(int k=j+1; k<=i; k++) s+=c[j][k]*ct[k][i]; ct[j][i]=-s/c[j][j]; } for(int i=0; i<n; i++) for(int j=0; j<n; j++) for(int k=0; k<n; k++) ans[i][j]+=ct[i][k]*bt[k][j]; for(int i=0; i<n; i++) for(int j=0; j<n; j++)printf("%.2f%c",ans[i][j],j==n-1?' ':' '); } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0; i<n; i++) for(int j=0; j<n; j++) scanf("%lf",&a[i][j]); LU(); } return 0; }
Gauss 消元
#include<stdio.h> #include<math.h> #include<algorithm> const double eps=1e-4; const int N=21; double a[N][N],b[N],x[N],s,t[N][N],ans[N][N]; int n; void gauss() { int i; for(int k=1; k<=n; k++) { for(i=k; i<=n&&fabs(a[i][k])<eps; i++); if(i!=k) { for(int j=k; j<=n; j++)std::swap(a[i][j],a[k][j]); std::swap(b[i],b[k]); } for(i=k+1; i<=n; i++) { s=a[i][k]/a[k][k]; for(int j=k; j<=n; j++)a[i][j]-=a[k][j]*s; b[i]-=b[k]*s; } } for(i=n; i>=1; --i) { s=b[i]; for(int j=i+1; j<=n; j++)s-=x[j]*a[i][j]; x[i]=s/a[i][i]; if(fabs(x[i])<eps)x[i]=0; } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) scanf("%lf",&t[i][j]),a[i][j]=t[i][j]; b[i]=0; } for(int k=1; k<=n; k++) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++)a[i][j]=t[i][j]; b[i]=0; } b[k]=1; gauss(); for(int i=1; i<=n; i++)ans[i][k]=x[i]; } for(int i=1; i<=n; i++) for(int j=1; j<=n; j++)printf("%.2f%c",ans[i][j],j==n?' ':' '); } return 0; }