蓝桥杯C/C++ 基础练习 矩阵乘法 C语言

题目:
在这里插入图片描述
思路分析:
     题目要求输入N阶矩阵,可以动态定义二维数组A[N][N]来存储该矩阵A。由于矩阵A的M次幂也是N阶矩阵,那么需要定义另一个数组B[N][N]来存储该矩阵。
     在继续分析之前需要明确矩阵的乘法规则(举例如下图图1,不清楚者可自行百度,此处不再赘述)。由于矩阵A的0次幂是N阶单位矩阵,1次幂是其本身,所以本题难点是其M次幂(M≥2)的求解。
     下面详细分析M次幂(M≥2)的求解:
          以三阶矩阵,求其3次幂为例。A3 = A×A×A =B0×A×A=B1×A=B2,需要循环两次,每次利用B[N][N]接收每次产生的结果。因此大循环是需要将矩阵B循环乘以A矩阵。当利用矩阵乘法规则计算时,我本想直接利用每次计算后的bij元素更新,类似bij=bij×aij。但是发现在计算下一个元素时还会用到bij,因此每次计算一个新元素都需要一个变量储存,共需要N×N个,由于N不固定,无法提前定义N×N个变量。所以想到再动态定义一个数组C[N][N]来存储。
在这里插入图片描述

图1 计算规则

     那么如何循环计算每个元素呢?
     寻找规律:如图2,A3 = A×A×A =B0×A×A=B1×A=B2,要求出每个Bi,都要包括3层小循环,每次求出一个元素:下图2中三行之和为一个元素,即:[0 0]×[0 0]+[0 1]×[1 0]+[0 2]×[2 0],存入到C[0][0]中。这是一个小循环,又要分别求出行列3×3个元素,外套两层循环。
在这里插入图片描述

图2 寻找规律

程序总体思路:
(半路出家,程序流程图不太会,见谅)
在这里插入图片描述

图3 程序流程图

代码如下:
运行环境:Code::Blocks 20.20

 #include <stdio.h>


 int main(void)
 {
     int N, M, i, j, k = 0, l;

     scanf("%d %d", &N, &M);

     int A[N][N], B[N][N], C[N][N];
/*键入值A[N][N]矩阵*/
     for(i = 0; i < N; i++)
     {
         for(j = 0; j < N; j++)
         {
             scanf("%d", &A[i][j]);
         }
     }
/*初始化B[N][N],方便后续计算*/
    for(i = 0; i < N; i++)
     {
         for(j = 0; j < N; j++)
         {
             B[i][j] = A[i][j];
         }

     }


     if(0 == M)
     {
/*打印 M = 0 时的结果,注意:矩阵的0次幂是单位矩阵*/
        for(i = 0; i < N; i++)
         {
             for(j = 0; j < N; j++)
             {
                 if(i == j)
                 {

                     printf("1 ");
                 }else{
                     printf("0 ");
                 }
             }
             printf("\n");
         }
         
     }else if(1 == M){
/*打印 M = 1 时的结果*/
        for(i = 0; i < N; i++)
         {
             for(j = 0; j < N; j++)
             {
                 printf("%d ", B[i][j]);
             }
             printf("\n");
         }
         
     }else{
/*此处为重点:最里面的循环是求出矩阵乘积的一个元素,同时将其存入数组C[][]中,第二层和第三层
是求出N×N个元素,最外面求M次幂,即上文中提到的:A×A×A =B0×A×A=B1×A=B2,矩阵A的值是不改变的,
只有矩阵B的值改变,就是将C[][]中的元素赋值给B[][]中的过程*/
         while(--M > 0)
         {
             for(i = 0; i < N; i++)
             {
                 for(j = 0; j < N; j++)
                 {
                     l = 0;
                     for(k = 0; k < N; k++)
                     {
                         l = B[i][k]*A[k][j]+l;
                     }
                     C[i][j] = l;
                 }
             }

             for(i = 0; i < N; i++)
             {
                 for(j = 0; j < N; j++)
                 {
                     B[i][j] = C[i][j];
                 }
             }
         }
/*打印 M >= 2 时的结果*/
         for(i = 0; i < N; i++)
         {
             for(j = 0; j < N; j++)
             {
                 printf("%d ", B[i][j]);
             }
             printf("\n");
         }

     }


     return 0;
 }
/*菜鸟一枚,请多指教*/
End
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值