zoukankan      html  css  js  c++  java
  • (模板)求逆矩阵luoguP4783

    题目链接:https://www.luogu.org/problem/P4783

    题意:求矩阵的逆。

    思路:高斯消元法求矩阵的逆,n为400,卡常,我是开了O2优化才AC的。。

    AC代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define R register int
    using namespace std;
    
    const int maxn=405;
    const int MOD=1e9+7;
    int n;
    
    struct Matrix{
        int m[maxn][maxn];
        void SWAP(int x,int y){   //交换两行
            for(R i=1;i<=n;++i)
                swap(m[x][i],m[y][i]);
        }
        void MUL(int x,int k){    //对一行乘上k
            for(R i=1;i<=n;++i)
                m[x][i]=(1LL*m[x][i]*k%MOD+MOD)%MOD;
        }
        void MULADD(int x,int y,int k){ //将第y行乘上k加到第x行上去
            for(R i=1;i<=n;++i)
                m[x][i]=((m[x][i]+1LL*m[y][i]*k%MOD)%MOD+MOD)%MOD;
        }
    }A,B;
    
    int qpow(int a,int b){   //求逆元
        int ret=1;
        while(b){
            if(b&1) ret=1LL*ret*a%MOD;
            a=1LL*a*a%MOD;
            b>>=1;
        }
        return ret;
    }
    
    void Invmatrix(){
        for(R i=1;i<=n;++i){
            if(!A.m[i][i]){
                for(R j=i+1;j<=n;++j)
                    if(A.m[j][i]){
                        B.SWAP(i,j);
                        A.SWAP(i,j);
                        break;
                    }
            }
            if(!A.m[i][i]){  //没有逆矩阵
                puts("No Solution");
                return;
            }
            int tmp=qpow(A.m[i][i],MOD-2);
            B.MUL(i,tmp);
            A.MUL(i,tmp);    //系数化为1
            for(R j=i+1;j<=n;++j){  //消元
                tmp=-A.m[j][i];
                B.MULADD(j,i,tmp);
                A.MULADD(j,i,tmp);
            }
        }    
        for(R i=n-1;i>=1;--i)  //回带
            for(R j=i+1;j<=n;++j){
                int tmp=-A.m[i][j];
                B.MULADD(i,j,tmp);
                A.MULADD(i,j,tmp);
            }
        for(R i=1;i<=n;++i){
            for(R j=1;j<=n;++j){
                printf("%d",B.m[i][j]);
                if(j!=n) printf(" ");
            }
            printf("
    ");
        }
    }
    
    int main(){
        scanf("%d",&n);
        for(R i=1;i<=n;++i)
            for(R j=1;j<=n;++j)
                scanf("%d",&A.m[i][j]);
        for(R i=1;i<=n;++i){
            for(R j=1;j<=n;++j)
                B.m[i][j]=0;
            B.m[i][i]=1;
        }
        Invmatrix();
        return 0;
    }
  • 相关阅读:
    java—连连看-实现封装
    java—连连看GUI
    连连看--产生随机数
    勇者斗恶龙
    在ctex环境下利用Metapost作图
    [leetcode] Binary Tree Postorder Traversal
    [leetcode] Binary Tree Maximum Path Sum
    [leetcode] Binary Tree Level Order Traversal II
    [leetcode] Binary Tree Level Order Traversal
    [leetcode] Binary Tree Inorder Traversal
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/11764185.html
Copyright © 2011-2022 走看看