藍橋杯-基礎練習 矩陣乘法

矩陣乘法

資源限制
時間限制:1.0s 內存限制:512.0MB
問題描述
  給定一個N階矩陣A,輸出A的M次冪(M是非負整數)
  例如:
  A =
  1 2
  3 4
  A的2次冪
  7 10
  15 22
輸入格式
  第一行是一個正整數N、M(1<=N<=30, 0<=M<=5),表示矩陣A的階數和要求的冪數
  接下來N行,每行N個絕對值不超過10的非負整數,描述矩陣A的值
輸出格式
  輸出共N行,每行N個整數,表示A的M次冪所對應的矩陣。相鄰的數之間用一個空格隔開
樣例輸入

2 2
1 2
3 4

樣例輸出

7 10
15 22

思路:
首先了解矩陣的乘法知道如何實現,矩陣乘法的代碼:

for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
        for(int k=0;k<n;k++)
             c[i][j]+=b[i][k]*a[k][j];

之後解決m次方的問題:
首先考慮特殊情況當m == 0時,矩陣的0次方爲單位矩陣,對角線元素是1,其餘元素是0,也就是當i==j時輸出1,i!=j時輸出0。

再考慮m!=0的情況,當m!=0時,首先用一個數組b來存a中的元素,在做乘法運算時是矩陣b*矩陣a,再用一個數組c存兩者的乘積,再通過循環把乘積(c)的值附給a,存乘積的數組©重新賦值爲0。循環m-1次,因爲2次方時a乘一次a,3次方是a乘兩次a,所以m次方是a乘m-1次a。

完整代碼:
一種方法:

#include <iostream>
#include<cstring>
typedef long long ll;
using namespace std;
int n,m;
struct mat              //矩陣結構體,也可以定義二維數組
{
    ll a[35][35];
};
int main()
{
    mat x,y;
    cin>>n>>m;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            cin>>x.a[i][j];
            y.a[i][j]=x.a[i][j];
        }
    }
    if(m==0)                    //當m==1時(矩陣的0次方)是單位矩陣(i==j)時等於1,(i!=j)時等於0
    {
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(j!=n-1)
                {
                    if(i==j)
                    {
                        cout<<"1 ";
                    }
                    else
                    {
                        cout<<"0 ";
                    }
                }
                else
                {
                    if(i==j)
                    {
                        cout<<"1"<<endl;;
                    }
                    else
                    {
                        cout<<"0"<<endl;
                    }
                }
            }
        }
    //上面的輸出格式每一行之後沒有空格直接換行
    //但是藍橋杯好像沒有那麼細緻可以每行最後一個元素後面有空格
    //也就是這樣,這樣可以少幾行代碼
    /*for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(i==j)
            {
                cout<<"1 ";
            }
            else
            {
                cout<<"0 ";
            }
        }
        cout<<endl;
    }*/
    }
    else
    {
        mat res;                        
        memset(res.a,0,sizeof(res.a));      //也可以定義在主函數外面,這樣就不用清空了
        m=m-1;					//m次方(二次方就是乘一次,三次方就是乘兩次,所以m先減1)當然可以wile(--m)前置--
        while(m--)
        {
            //矩陣乘法
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<n; j++)
                {
                    for(int k=0; k<n; k++)
                    {
                        res.a[i][j]+=x.a[i][k]*y.a[k][j];       //矩陣的乘法
                    }
                }
            }
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<n; j++)
                {
                    y.a[i][j]=res.a[i][j];          //每乘一次得的結果就附給y
                    res.a[i][j]=0;                //res歸零,重新保存新的一輪乘積
                }
            }
        }
        //和上面的輸出格式一樣
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(j!=n-1)
                {
                    cout<<y.a[i][j]<<" ";
                }
                else
                {
                    cout<<y.a[i][j]<<endl;
                }
            }
        }
    }
    return 0;
}

另一種方法 (因爲第一種方法中介紹的很詳細註釋寫的也很詳細就不寫註釋了):

#include <iostream>
#include<cstring>
typedef long long ll;
using namespace std;
int n,m;
ll a[35][35];
ll b[35][35];
ll c[35][35];
int main()
{
    cin>>n>>m;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            cin>>a[i][j];
            b[i][j]=a[i][j];
        }
    }
    if(m==0)
    {
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(i==j)
                {
                    cout<<"1 ";
                }
                else
                {
                    cout<<"0 ";
                }
            }
            cout<<endl;
        }
    }
    else
    {
        while(--m)
        {
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<n; j++)
                {
                    for(int k=0; k<n; k++)
                    {
                        c[i][j]+=b[i][k]*a[k][j];
                    }
                }
            }
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<n; j++)
                {
                    a[i][j]=c[i][j];
                    c[i][j]=0;
                }
            }
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                cout<<a[i][j]<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章