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(); 
    }

      

  • 相关阅读:
    洛谷p1017 进制转换(2000noip提高组)
    Personal Training of RDC
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Eurasia
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.
    Asia Hong Kong Regional Contest 2019
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia
    XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix.
    XVIII Open Cup named after E.V. Pankratiev. GP of SPb
    卜题仓库
    2014 ACM-ICPC Vietnam National First Round
  • 原文地址:https://www.cnblogs.com/flipped/p/5221201.html
Copyright © 2011-2022 走看看