数学之矩阵求逆

矩阵求逆:

现有AB两个矩阵,若使A*B=E,则称B为A的逆元

so怎么求B咧?

既然A*B=E,那么我们不妨对A进行一阵乱搞,同时对单位矩阵E进行同样的乱搞,我们会神奇的发现,当A被搞成E的时候,原本的E就被搞成了A的逆元,也就是B。

那我们就只用写出把A搞成E的程序就好了,这个可以用高斯消元做。

高斯消元详情见这里:biu~~~~

(刚看完大佬的退役博,悲伤....)(嗯一定要好好学习天天向上)

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n;
long long mo=1000000007;
int a[101][202];
int ksm(long long a,long long b,long long p)
{int r=1;
    while(b)
    {if(b&1)r=r*a%p;
      a=a*a%p;
      b/=2;
    }
    return r;
}
int main()
{
    //scanf("%d%lld",&n,&mo);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {for(int j=1;j<=n;j++)
      scanf("%d",&a[i][j]);
    }
    int m=2*n;
    for(int i=1;i<=n;i++)
    { a[i][n+i]=1;
    }
    
    for(int i=1;i<=n;i++)
    {int bj=-1;
        for(int j=i;j<=n;j++)
        {if(a[j][i])
         {bj=j;
          break;
         }
         if(bj==-1)
         {printf("No solution");return 0;}
        }
         for(int j=1;j<=2*n;j++)
            swap(a[i][j],a[bj][j]);
         for(int j=i+1;j<=n;j++)
         {int ny=(long long)a[j][i]*ksm(a[i][i],mo-2,mo)%mo;
          for(int k=1;k<=2*n;k++)
           {a[j][k]=(a[j][k]-(long long)a[i][k]*ny%mo+mo)%mo;
           }
         }
    }
    for(int i=n;i>=1;i--)
    {for(int j=i-1;j>=1;j--)
       {int ny=(long long)a[j][i]*ksm(a[i][i],mo-2,mo)%mo;
         for(int k=1;k<=2*n;k++)
         {a[j][k]=(a[j][k]-(long long)a[i][k]*ny%mo+mo)%mo;
         }
       }
    } 
    for(int i=1;i<=n;i++)
    {int ny=ksm(a[i][i],mo-2,mo);
     for(int j=1;j<=2*n;j++)
      {a[i][j]=(long long)a[i][j]*ny%mo;
      }
    }
    for(int i=1;i<=n;i++)
    { for(int j=n+1;j<=2*n;j++)
      {printf("%d ",a[i][j]);
      }
      printf("\n");
    }
}

这是蒟阵求逆,不是矩阵求逆(放在矩阵求逆里的题会RE的,算简单的还可以,嗯。。。凑合着看吧)(瞬间溜)

猜你喜欢

转载自www.cnblogs.com/lcez56jsy/p/10674940.html