蓝桥杯-基础练习 矩阵乘法

矩阵乘法

资源限制
时间限制: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;
}
发布了93 篇原创文章 · 获赞 106 · 访问量 5234

猜你喜欢

转载自blog.csdn.net/qq_45856289/article/details/105225604