下面来讨论如何对矩阵求逆
先看实数中的如何求两个数的积为1
如:
对233求逆时,我们令a=233,b=1要把a变化为1,即a/=233这时对b进行同样的操作,b/=233现在a=1,b=1/233,b,ab=1
同理,矩阵也可以用相同的方法来求逆,不过上面的初等变换是除法
所以我们要重新定义初等变换:
- 将某两行进行交换
- 将某一行的所有元素乘以k
- 将某一行的所有元素乘以k加到另一行
这不是就是高斯消元吗?
用高斯消元把给出的矩阵消成上三角矩阵,再消成单位矩阵,同时在右边另一个初值为单位矩阵的矩阵上做同样的操作,得到的矩阵即为该矩阵的逆矩阵。
#include#include #include #include using namespace std;const int N=405,md=1000000007;int n,i,j,k,x,a[N][N*2];int pw(int a,int b){ int rtn=1; while(b) { if(b&1) rtn=1ll*rtn*a%md; a=1ll*a*a%md; b>>=1; } return rtn;}int main(){ scanf("%d",&n); for(i=1;i<=n;++i) { for(j=1;j<=n;++j) scanf("%d",a[i]+j); a[i][n+i]=1; } for(i=1;i<=n;++i) { for(j=i;j<=n;++j) if(a[j][i]) break; if(j>n) { printf("No Solution"); return 0; } if(i!=j) for(k=i;k<=2*n;++k) swap(a[i][k],a[j][k]); x=pw(a[i][i],md-2); for(k=i;k<=2*n;++k) a[i][k]=1ll*a[i][k]*x%md; for(j=i+1;j<=n;++j) { x=a[j][i]; for(k=i;k<=2*n;++k) a[j][k]=(a[j][k]-1ll*a[i][k]*x%md+md)%md; } } for(i=n;i>1;--i) { for(j=i-1;j>=1;--j) { x=a[j][i]; for(k=i;k<=2*n;++k) a[j][k]=(a[j][k]-1ll*x*a[i][k]%md+md)%md; } } for(i=1;i<=n;++i) { for(j=n+1;j<=2*n;++j) printf("%d ",a[i][j]); puts(""); } return 0;}