zoukankan      html  css  js  c++  java
  • 求矩阵的逆

    不甘心寒假就要收尾了。

    回到学校,整理完行李,再收拾一下U盘里的东西。看到刚学线代那会儿瞎整的求矩阵的逆的代码。

    #include <iostream>
    #include <cstring>
    using namespace std;
    int a[11][11],b[11][11],M[11][11],A[11][11];
    int n,nx,ans,ans2,nx2;
    int c[11],co[11],tem[11],temp[11],co2[11];
    int gcd(int a,int b){
         return (a%b)?gcd(b,a%b):b;
    }
    void hj(){
        int g;
        g=M[1][1];
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
          if(g==1||!g)return;
          g=gcd(g,M[i][j]);
        }
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          M[i][j]/=g;
        if (!(ans2%g))
        {
                ans2/=g;
                if(ans2!=1&&ans2>0){
                cout<<"1/"<<ans2<<"*"<<endl;
                return;
                }
                if(ans2!=1&&ans2<0){
                cout<<"-1/"<<ans2<<"*"<<endl;
                return;
                }
        }else {
            if(ans2>0)cout<<g<<"/"<<ans2<<"*"<<endl;
            if(ans2<0)cout<<"-"<<g<<"/"<<-ans2<<"*"<<endl;
            return;
        }
    }
    void ds(int i,int j){//构造代数余子式 
        int row,col;
        row=col=1;
        for(int k=1;k<=n;k++){
            col=1;
            if (k!=i){//除了第i行 
                for(int v=1;v<=n;v++)
                    if(v!=j){//除了第j列 
                        b[row][col]=a[k][v];//第row行第col列为 
                        col++;
                    }
                row++;    
            }    
        }    
    }
    void add(int r){
        if(r==n){
            int sum=1;
            for(int i=1;i<n;i++)
                    sum*=tem[i];
            if(nx %2)
                ans-=sum;//奇数 ,-1 
            else ans+=sum;
        }else{
        for(int i=1;i<n;i++)
        {
            if(!co[i]){
                co[i]=1;
                int nxs=0;
                for(int j=i+1;j<n;j++)
                    if(j<n&&co[j])nxs++;
                nx+=nxs;
                tem[r]=b[r][i];
                add(r+1);
                tem[r]=0;
                nx-=nxs;
                co[i]=0;
            }
        }
        }
    }
    void add2(int r){
        if(r==n+1){
            int sum=1;
            for(int i=1;i<=n;i++)
                    sum*=temp[i];
            if(nx2 %2)
                ans2-=sum;
            else ans2+=sum;
        }else{
        for(int i=1;i<=n;i++)//现在是第r行,我取第i列的元素 
        {
            if(!co2[i]){
                co2[i]=1;
                int nxs=0;
                for(int j=i+1;j<=n;j++)//列举比i大的数 
                    if(co2[j])nxs++;//如果第j列已选择,逆序数+1 
                nx2+=nxs;//统计到总的逆序数里 
                temp[r]=a[r][i];
                add2(r+1);
                temp[r]=0;
                nx2-=nxs;
                co2[i]=0;
            }
        }
        }
    }
    void work(){
            for(int i=1;i<=n;i++)
                 for(int j=1;j<=n;j++) 
                 {
                     ds(i,j);
                     memset(co,0,sizeof(co));
                     memset(tem,0,sizeof(tem));
                     nx=0;
                     ans=0;
                     add(1);
                     if((i+j)%2)M[j][i]=-ans;//代数余子式不要忘记-1的i+j次方 
                     else M[j][i]=ans;
                 }    
    }
    void ansprintf(){
        cout<<"答案是:"<<endl;
        hj();    
        for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            cout<<M[i][j]<<" ";
        cout<<endl;
        }
    }
    void judge(){
        memset(co2,0,sizeof(co2));
        memset(temp,0,sizeof(temp));
        nx2=0;
        ans2=0;
        add2(1);
        if(ans2)
        {
        work();
        ansprintf();
        }
        else cout<<"这是一个奇异矩阵(等于0),不能求逆哦!"<<endl;
    }
    void init(){
        cin>>n;
        
        if(!n){
            cout<<"再见!"<<endl;
            getchar();getchar(); }
        else{
         if(n>10 or n<0)cout<<"TAT 这么难,不要耍宝宝啊!"<<endl;
        else 
        {
            cout<<"那现在你可以输入这个矩阵了,我不会算有分数和小数的矩阵哦!
    (请化为全部是整数的矩阵再输入)"<<endl;
            memset(c,0,sizeof(c));
            for(int i=1;i<=n;i++)
                 for(int j=1;j<=n;j++)
                    cin>>a[i][j];
            judge();    
        }
        cout<<"继续输入你要求解的矩阵的阶数(输入0结束程序):"<<endl;
        init(); 
        }
    }
    int main(){
        cout<<"输入你要求解的矩阵的阶数(输入0结束程序):"<<endl;
        init(); 
    }

      

  • 相关阅读:
    HDU 6182 A Math Problem 水题
    HDU 6186 CS Course 位运算 思维
    HDU 6188 Duizi and Shunzi 贪心 思维
    HDU 2824 The Euler function 欧拉函数
    HDU 3037 Saving Beans 多重集合的结合 lucas定理
    HDU 3923 Invoker Polya定理
    FZU 2282 Wand 组合数学 错排公式
    HDU 1452 Happy 2004 数论
    HDU 5778 abs 数论
    欧拉回路【判断连通+度数为偶】
  • 原文地址:https://www.cnblogs.com/flipped/p/5221201.html
Copyright © 2011-2022 走看看