算法训练 矩阵乘方  
时间限制: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:

 #include<iostream>
#include<memory.h>
using namespace std; #define MAX_NUM 2 //数组copy 将源数组s复制给目的数组o
void arrcopy(int s[][MAX_NUM], int o[][MAX_NUM])
{
for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
o[i][j] = s[i][j];
}
}
} /*
矩阵乘法
m:模
*/
void matrixMul(int x[][MAX_NUM], int y[][MAX_NUM], int m)
{
int t[MAX_NUM][MAX_NUM];
memset(t, , sizeof(t)); for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
for (int k = ; k < MAX_NUM; k++)
{
t[i][j] += x[i][k] * y[k][j];
t[i][j] %= m;
}
}
} arrcopy(t , x); //最终结果保存在数组x
} //分情况处理
void dispose(int A[][MAX_NUM], int b, int m)
{
if (b == )
{
int tmp;
for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
if (i == j)
tmp = ;
else
tmp = ;
A[i][j] = tmp % m; //A为单位矩阵 A^b%m=I%m
}
}
return;
} if (b % == ) //A^b%m=(A^(b/2)%m)^2%m
{
dispose(A, b / , m);
matrixMul(A, A, m);
}
else //A^b%m=(A^(b-1)%m)*a%m
{
int t[MAX_NUM][MAX_NUM];
arrcopy(A , t);
dispose(A, b - , m);
matrixMul(A, t, m);
}
} int main()
{
int b, m;
scanf("%d%d", &b, &m); int A[MAX_NUM][MAX_NUM];
for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
scanf("%d", &A[i][j]);
}
} dispose(A, b, m); for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
printf("%d ", A[i][j] % m);
}
printf("\n");
} return ;
}

示例代码2:

 #include<iostream>
using namespace std; #define MAX_NUM 2 struct Matrix
{
int arr[MAX_NUM][MAX_NUM];
}; Matrix A; //矩阵乘法,与m取模,返回结果
Matrix mul(Matrix x, Matrix y, int m)
{
Matrix t;
for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
t.arr[i][j] = ;
for (int k = ; k < MAX_NUM; k++)
{
t.arr[i][j] += x.arr[i][k] * y.arr[k][j];
t.arr[i][j] %= m;
}
}
}
return t;
} //分情况处理
Matrix dispose(Matrix A, int b, int m)
{
if (b == )
{
for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
if (i == j)
A.arr[i][j] = % m;
else
A.arr[i][j] = % m;
}
}
return A;
} Matrix t = dispose(A, b / , m);
if (b % == )
return mul(t, t, m);
else //当b为奇数时,先计算A^(b/2)次方,再乘以A,即A^(b-1)*A
//例如,b=5,b/2=2,即A^5 = (A^2 * A^2) * A
return mul(mul(t, t, m), A, m);
} int main()
{
int b, m;
scanf("%d%d", &b, &m); for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
scanf("%d", &A.arr[i][j]);
}
} Matrix p = dispose(A, b, m); for (int i = ; i < MAX_NUM; i++)
{
for (int j = ; j < MAX_NUM; j++)
{
printf("%d ", p.arr[i][j]);
}
printf("\n");
} return ;
}

蓝桥杯 算法训练 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. NumPy来自数值范围的数组

    NumPy - 来自数值范围的数组 这一章中,我们会学到如何从数值范围创建数组. numpy.arange 这个函数返回ndarray对象,包含给定范围内的等间隔值. numpy.arange(sta ...

  2. Softmax回归 softMax回归与logistic回归的关系

    简介 在本节中,我们介绍Softmax回归模型,该模型是logistic回归模型在多分类问题上的推广,在多分类问题中,类标签  可以取两个以上的值. Softmax回归模型对于诸如MNIST手写数字分 ...

  3. activity启动模式之standard

    activity启动模式之standard 一.简介 这种模式是默认的,不用我们自己设定 就像一只叠加在栈中 如果退出,就一个个退出,其实就是我们自己用手机的那种感受 二.代码实例 activityL ...

  4. PhpStorm怎么用,PhpStorm常用快捷键教程

    设置快捷键:File -> Settings -> IDE Settings -> Keymap -> 选择“Eclipse” -> 然后“Copy”一份 ->再个 ...

  5. mysql数据库(一):建表与新增数据

    一. 学习目标 理解什么是数据库,什么是表 怎样创建数据库和表(create) 怎样往表里插入数据(insert) 怎样修改表里的数据(update) 怎样删除数据库,表以及数据(delete) 二. ...

  6. lftp使用

    lftp -c 'pget -n 5 ftp://user:password@ftpserver/test.txt'  5 线程数 安装: yum install lftp -y使用语法:lftp - ...

  7. $fn、$extends $fn.extends的用法,jquery的插件开发

    原文链接:http://caibaojian.com/jquery-extend-and-jquery-fn-extend.html Query.fn.extend(); jQuery.extend( ...

  8. 【CSAPP】一、计算机系统漫游

    一.位+上下文 文本文件 / 二进制文件: 文本文件是只由ASCII码构成的文件 二.从源代码到可执行文件的顺序 源代码 ——> 可执行文件(机器代码)共有四步: 全过程代码 gcc hello ...

  9. .net学习路线(转)

    入门篇1.         学习面向对象(OOP)的编程思想 许多高级语言都是面向对象的编程,.NET也不例外.如果您第一次接触面向对象的编程,就必须理解类.对象.字段.属性.方法和事件.封装.继承和 ...

  10. pgrep 和 pkill 使用小记

    在停止指定进程时,经常使用如下命令: kill `ps aux | grep -w program_name | grep -v grep | awk '{print $2}'` 使用 pgrep 和 ...