算法训练 矩阵乘方  
时间限制:1.0s   内存限制:512.0MB
问题描述
  给定一个矩阵A,一个非负整数b和一个正整数m,求A的b次方除m的余数。
  其中一个nxn的矩阵除m的余数得到的仍是一个nxn的矩阵,这个矩阵的每一个元素是原矩阵对应位置上的数除m的余数。
  要计算这个问题,可以将A连乘b次,每次都对m求余,但这种方法特别慢,当b较大时无法使用。下面给出一种较快的算法(用A^b表示A的b次方):
  若b=0,则A^b%m=I%m。其中I表示单位矩阵。
  若b为偶数,则A^b%m=(A^(b/2)%m)^2%m,即先把A乘b/2次方对m求余,然后再平方后对m求余。
  若b为奇数,则A^b%m=(A^(b-1)%m)*a%m,即先求A乘b-1次方对m求余,然后再乘A后对m求余。
  这种方法速度较快,请使用这种方法计算A^b%m,其中A是一个2x2的矩阵,m不大于10000。
输入格式
  输入第一行包含两个整数b, m,第二行和第三行每行两个整数,为矩阵A。
输出格式
  输出两行,每行两个整数,表示A^b%m的值。
样例输入
2 2
1 1
0 1
样例输出
1 0
0 1
 
题目解析:
  题目中已经给出了解题思路,只需分情况讨论 b 为不同情况时,矩阵该怎样去乘即可。
  因为C/C++中无法返回二维数组,所以给出两种代码,一种是常规方式,一种为结构体,但思路如题所示。后者较前者的时间复杂度更高,但空间复杂度大致相同。
 
示例代码1:

  1. #include<iostream>
  2. #include<memory.h>
  3. using namespace std;
  4.  
  5. #define MAX_NUM 2
  6.  
  7. //数组copy 将源数组s复制给目的数组o
  8. void arrcopy(int s[][MAX_NUM], int o[][MAX_NUM])
  9. {
  10. for (int i = ; i < MAX_NUM; i++)
  11. {
  12. for (int j = ; j < MAX_NUM; j++)
  13. {
  14. o[i][j] = s[i][j];
  15. }
  16. }
  17. }
  18.  
  19. /*
  20. 矩阵乘法
  21. m:模
  22. */
  23. void matrixMul(int x[][MAX_NUM], int y[][MAX_NUM], int m)
  24. {
  25. int t[MAX_NUM][MAX_NUM];
  26. memset(t, , sizeof(t));
  27.  
  28. for (int i = ; i < MAX_NUM; i++)
  29. {
  30. for (int j = ; j < MAX_NUM; j++)
  31. {
  32. for (int k = ; k < MAX_NUM; k++)
  33. {
  34. t[i][j] += x[i][k] * y[k][j];
  35. t[i][j] %= m;
  36. }
  37. }
  38. }
  39.  
  40. arrcopy(t , x); //最终结果保存在数组x
  41. }
  42.  
  43. //分情况处理
  44. void dispose(int A[][MAX_NUM], int b, int m)
  45. {
  46. if (b == )
  47. {
  48. int tmp;
  49. for (int i = ; i < MAX_NUM; i++)
  50. {
  51. for (int j = ; j < MAX_NUM; j++)
  52. {
  53. if (i == j)
  54. tmp = ;
  55. else
  56. tmp = ;
  57. A[i][j] = tmp % m; //A为单位矩阵 A^b%m=I%m
  58. }
  59. }
  60. return;
  61. }
  62.  
  63. if (b % == ) //A^b%m=(A^(b/2)%m)^2%m
  64. {
  65. dispose(A, b / , m);
  66. matrixMul(A, A, m);
  67. }
  68. else //A^b%m=(A^(b-1)%m)*a%m
  69. {
  70. int t[MAX_NUM][MAX_NUM];
  71. arrcopy(A , t);
  72. dispose(A, b - , m);
  73. matrixMul(A, t, m);
  74. }
  75. }
  76.  
  77. int main()
  78. {
  79. int b, m;
  80. scanf("%d%d", &b, &m);
  81.  
  82. int A[MAX_NUM][MAX_NUM];
  83. for (int i = ; i < MAX_NUM; i++)
  84. {
  85. for (int j = ; j < MAX_NUM; j++)
  86. {
  87. scanf("%d", &A[i][j]);
  88. }
  89. }
  90.  
  91. dispose(A, b, m);
  92.  
  93. for (int i = ; i < MAX_NUM; i++)
  94. {
  95. for (int j = ; j < MAX_NUM; j++)
  96. {
  97. printf("%d ", A[i][j] % m);
  98. }
  99. printf("\n");
  100. }
  101.  
  102. return ;
  103. }

示例代码2:

  1. #include<iostream>
  2. using namespace std;
  3.  
  4. #define MAX_NUM 2
  5.  
  6. struct Matrix
  7. {
  8. int arr[MAX_NUM][MAX_NUM];
  9. };
  10.  
  11. Matrix A;
  12.  
  13. //矩阵乘法,与m取模,返回结果
  14. Matrix mul(Matrix x, Matrix y, int m)
  15. {
  16. Matrix t;
  17. for (int i = ; i < MAX_NUM; i++)
  18. {
  19. for (int j = ; j < MAX_NUM; j++)
  20. {
  21. t.arr[i][j] = ;
  22. for (int k = ; k < MAX_NUM; k++)
  23. {
  24. t.arr[i][j] += x.arr[i][k] * y.arr[k][j];
  25. t.arr[i][j] %= m;
  26. }
  27. }
  28. }
  29. return t;
  30. }
  31.  
  32. //分情况处理
  33. Matrix dispose(Matrix A, int b, int m)
  34. {
  35. if (b == )
  36. {
  37. for (int i = ; i < MAX_NUM; i++)
  38. {
  39. for (int j = ; j < MAX_NUM; j++)
  40. {
  41. if (i == j)
  42. A.arr[i][j] = % m;
  43. else
  44. A.arr[i][j] = % m;
  45. }
  46. }
  47. return A;
  48. }
  49.  
  50. Matrix t = dispose(A, b / , m);
  51. if (b % == )
  52. return mul(t, t, m);
  53. else //当b为奇数时,先计算A^(b/2)次方,再乘以A,即A^(b-1)*A
  54. //例如,b=5,b/2=2,即A^5 = (A^2 * A^2) * A
  55. return mul(mul(t, t, m), A, m);
  56. }
  57.  
  58. int main()
  59. {
  60. int b, m;
  61. scanf("%d%d", &b, &m);
  62.  
  63. for (int i = ; i < MAX_NUM; i++)
  64. {
  65. for (int j = ; j < MAX_NUM; j++)
  66. {
  67. scanf("%d", &A.arr[i][j]);
  68. }
  69. }
  70.  
  71. Matrix p = dispose(A, b, m);
  72.  
  73. for (int i = ; i < MAX_NUM; i++)
  74. {
  75. for (int j = ; j < MAX_NUM; j++)
  76. {
  77. printf("%d ", p.arr[i][j]);
  78. }
  79. printf("\n");
  80. }
  81.  
  82. return ;
  83. }

蓝桥杯 算法训练 ALGO-60 矩阵乘法的更多相关文章

  1. Java实现 蓝桥杯 算法训练 矩阵乘法

    算法训练 矩阵乘法 时间限制:1.0s 内存限制:512.0MB 提交此题 问题描述 输入两个矩阵,分别是ms,sn大小.输出两个矩阵相乘的结果. 输入格式 第一行,空格隔开的三个正整数m,s,n(均 ...

  2. Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)

    试题 算法训练 猴子吃包子 问题描述 从前,有一只吃包子很厉害的猴子,它可以吃无数个包子,但是,它吃不同的包子速度也不同:肉包每秒钟吃x个:韭菜包每秒钟吃y个:没有馅的包子每秒钟吃z个:现在有x1个肉 ...

  3. Java实现蓝桥杯 算法训练 大等于n的最小完全平方数

    试题 算法训练 大等于n的最小完全平方数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输出大等于n的最小的完全平方数. 若一个数能表示成某个自然数的平方的形式,则称这个数为完全平 ...

  4. java实现 蓝桥杯 算法训练 Password Suspects

    问题描述 在年轻的时候,我们故事中的英雄--国王 Copa--他的私人数据并不是完全安全地隐蔽.对他来说是,这不可接受的.因此,他发明了一种密码,好记又难以破解.后来,他才知道这种密码是一个长度为奇数 ...

  5. 蓝桥杯算法训练<一>

    一.图形显示 此题虽然简单,但是需啊哟注意的是,每个“*”后边有一个空格] 问题描述 编写一个程序,首先输入一个整数,例如5,然后在屏幕上显示如下的图形(5表示行数): * * * * * * * * ...

  6. 蓝桥杯算法训练 java算法 表达式求值

    问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输出格式 输出这个表达式的值. 样例输入 1-2+3*(4-5) 样例输出 - ...

  7. 蓝桥杯 算法训练 ALGO-34 纪念品分组

    算法训练 纪念品分组   时间限制:1.0s   内存限制:256.0MB 问题描述 元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作.为使得参加晚会的同学所获得的纪念品价值 相对均衡,他要把购 ...

  8. 蓝桥杯 算法训练 ALGO-36 传纸条

    算法训练 传纸条   时间限制:1.0s   内存限制:512.0MB 问题描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而 ...

  9. 蓝桥杯 算法训练 ALGO-142 P1103

    算法训练 P1103   时间限制:1.0s   内存限制:256.0MB 编程实现两个复数的运算.设有两个复数 和 ,则他们的运算公式为: 要求:(1)定义一个结构体类型来描述复数. (2)复数之间 ...

随机推荐

  1. Find Min In Rotated Sorted Array,寻找反转序列中最小的元素。

    问题描述:寻找反转序列中最小的元素. 算法分析:和寻找某个数是一个道理,还是利用二分查找,总体上分两种情况.nums[left]<=nums[mid],else.但是,在截取子序列的时候,有可能 ...

  2. 使用SpringMVC报错 Error creating bean with name 'conversionService' defined in class path resource [springmvc.xml]

    使用SpringMVC报错 Error creating bean with name 'conversionService' defined in class path resource [spri ...

  3. css属性(冷用法)

    1.pointer-events:none 元素永远不会成为鼠标事件的target. 2.not-allowed  禁止 3.-webkit-appearance: none; appearance ...

  4. python学习笔记(arange函数与linspace函数)

    上一篇提及到matplotlib模块.其中会涉及到numpy模块科学计数 这里总结两个数组生成函数 arange 与 linspace: #!/usr/bin/env python # -*- cod ...

  5. 提升 CSS 选择器性能的方法

    CSS 选择器性能损耗来自? CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,所以优化选择器的原则是应尽量避免使用消耗更多匹配时间的选择器.而在这之前我们需要了解CSS选择器匹配 ...

  6. 滚动条——WPF ScrollViewer的应用

    WPF ScrollViewer的应用   我们知道在一个限定高的窗体和容器中,想要把内容显示完是有些问题的,这个时候我们就要使用类似于浏览器的那个滚动条的效果了,在wpf中也同样如此,最近就碰到了这 ...

  7. IE兼容性测试工具IETester

    IE兼容性测试工具:IETester 1.这种做法,不能做到100%的覆盖: 2.实际的业务场景会比IEtester更符合.

  8. 【scala】getter和setter

    我们在用Java的时候经常把一些字段定义为private类型来完成封装,这样外界就无法访问. 如果外界访问或者修改该字段的时候,只能通过该字段提供的getter和setter方法来实现. 在Scala ...

  9. angular之 $watch 和$digest 和$apply和$observe的区别

    $watch 代表的就是对数据源的监听,当数据源发生变化,就会触发第二个参数的回调函数 $digest 代表触发一个数据源变化的事件 $apply 代表对于$digest的一个封装,他多了一个参数 . ...

  10. Angular路由的定义和使用

    一.什么是routing(路由) Almost all non-trivial, non-demo Single Page App (SPA) require multiple pages. A se ...