前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >求矩阵的逆

求矩阵的逆

作者头像
饶文津
发布2020-06-02 15:13:08
6210
发布2020-06-02 15:13:08
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏

不甘心寒假就要收尾了。

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

代码语言:javascript
复制
#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<<"那现在你可以输入这个矩阵了,我不会算有分数和小数的矩阵哦!\n(请化为全部是整数的矩阵再输入)"<<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(); 
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-02-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档