矩阵快速幂(新手做法)

news2024/11/20 6:30:05

  • 1.通过一个代码来了解矩阵乘法
  • 2.基本快速幂
  • 3.那么最后就是矩阵快速幂了
  • 4.练习模板:
  • 5.进阶运用,蓝桥杯15届省赛c语言组第9题

矩阵快速幂的学习流程:

  1. 矩阵乘法运算规则(线性代数基础)
  2. 快速幂的模板

1.通过一个代码来了解矩阵乘法

首先,先给出百度百科对于矩阵乘法的描述:
注意!!m x n表示m行n列
在这里插入图片描述

矩阵乘法的要点:
1.当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。
2.矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
3.乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和。

那么,根据这种描述,来写一个较为详细的小程序来模拟矩阵乘法

#include<iostream>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;
const int N = 1010;
int Matrix[N][N];  //存放最后的答案
int a[N][N];    //a,b分别是两个目标矩阵,a,b相乘得到Matrix
int b[N][N];

int row_a, row_b, col_a, col_b;

void Init(int (*a)[N],int (*b)[N])   //初始化
{
	//step 1
	//分别初始化a,b的行和列
	//由于a的列要等于b的行,所有只需要初始化:
	//(1)a的行 (2)a的列 (3)b的列
	time_t t;   //时间种子变量(必写)
	srand((unsigned)time(&t));  //这句话必须写,当作模板背就好了。
	//初始化a的行
	row_a = rand() % 10;
	while (!row_a) //不能为0
		row_a = rand() % 10;

	//初始化a的列
	col_a = rand() % 10;
	while (!col_a)  //不能为0
		col_a = rand() % 10;

	//初始化b的列
	col_b = rand() % 10;
	while (!col_b)
		col_b = rand() % 10;

	//a的列要等于b的行
	row_b = col_a;

	//step  2
	//初始化两个矩阵
	for (int i = 1; i <= row_a; i++)
		for (int j = 1; j <= col_a; j++)
			a[i][j] = rand() % 20;

	for (int i = 1; i <= row_b; i++)
		for (int j = 1; j <= col_b; j++)
			b[i][j] = rand() % 20;
}


void print(int(*a)[N],int n,int m)   //输出
{
	cout << "行n: " << n << " 列m: " << m << endl;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
			printf("%-5d", a[i][j]);  //左对齐
		cout << endl;
	}
	cout << endl << endl;
}


void Mul(int (*a)[N],int (*b)[N],int n,int m,int p)   //矩阵相乘
{
	//建议根据博客的那个百度百科的图一起模拟
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			for (int k = 1; k <= p; k++)
				Matrix[i][j] = Matrix[i][j] + a[i][k] * b[k][j];
}


int main()
{
	cout << "模拟一下矩阵乘法,首先给两个矩阵(使用随机函数来生成两个矩阵):"<<endl;
	Init(a, b);
	print(a,row_a,col_a);
	print(b,row_b,col_b);

	//初始化完成,开始矩阵乘法

	Mul(a,b,row_a,col_b,col_a);
	cout << "答案:" << endl;
	print(Matrix, row_a, col_b);
	return 0;
}

运行:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.基本快速幂

快速幂图解:
在这里插入图片描述

#include<iostream>
using namespace std;

long long int ans=1;
int main()
{
	int n;
	cout << " 输入n,表示将要算出2的n次幂:\n";
	cin >> n;
	int k = 2;
	while (n)
	{
		if ((n & 1)==1)  //说明二进制位上是1
		{
			ans = ans * k;
		}
		k = k * k;  //k*k相当于是2的幂次的乘2,因为二进制右移一位要乘2
		n = n / 2;
	}
	cout << "ans=" << ans << endl;
	return 0;
}

在这里插入图片描述
在这里插入图片描述

3.那么最后就是矩阵快速幂了

相当于把矩阵看成‘2’,然后算2n。当然实际上这个2是一个矩阵。换汤不换药哈。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
const int N = 101, mod = 1e9 + 7;
const int row = 10, col = 10;   //这里默认矩阵的行列都是10,可以自己改,只是为了方便(默认n*n阶矩阵)
struct Matrix
{
	long long int c[N][N];
	Matrix()   //默认构造函数
	{
		for (int i = 1; i <= N; i++)   //初始化为单位矩阵
			c[i][i] = 1;
	}
};
Matrix A, B;


Matrix operator *(const Matrix& x, const Matrix& y)  //重载运算符,不重载也行,但是为了使代码更加贴合快速幂模板,还是重载一下
{
	Matrix temp;
	for (int i = 1; i <= row; i++)
		for (int j = 1; j <= col; j++)
			temp.c[i][j] = 0;
	for(int i=1;i<=row;i++)
		for(int j=1;j<=col;j++)
			for (int k = 1; k <= row;k++)
				temp.c[i][j] = (temp.c[i][j] + x.c[i][k] * y.c[k][j]%mod)%mod;   //取模,防止数据溢出
	return temp;
}

void Init(Matrix& A)   //初始化矩阵
{
	time_t t;
	srand((unsigned)time(&t));
	for (int i = 1; i <= row; i++)
		for (int j = 1; j <= col; j++)
			A.c[i][j] = rand() % 20;

	for (int i = 1; i <= row; i++)
	{
		for (int j = 1; j <= col; j++)
			printf("%-5d", A.c[i][j]);
		cout << endl;
	}
}


void kuaisumi(Matrix& A,Matrix& B,int n)  //写一个快速幂的模板即可
{
	while (n)
	{
		if ((n & 1) == 1)
			B = B * A;
		A = A * A;
		n /= 2;
	}
}

int main()
{
	int n;
	cout << "随机初始化一个矩阵:"<<endl;
	Init(A);   //随机初始化一个矩阵
	cout << "接下来,计算矩阵A的n次幂:" << endl;
	cout << "请输入n:";
	cin >> n;
	cout << "最终矩阵:"<<endl;
	kuaisumi(A,B,n);
	for (int i = 1; i <= row; i++)
	{
		for (int j = 1; j <= col; j++)
			printf("%-10d", B.c[i][j]);
		cout << endl;
	}
	return 0;
}

4.练习模板:

矩阵快速幂点这里
代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 110,mod=1e9+7;
long long int n, m;


struct Matrix
{
	long long int c[N][N];
}A,B;

Matrix operator*(const Matrix& A, const Matrix& B)
{
	Matrix temp;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			temp.c[i][j] = 0;

	for(int i=1;i<=n;i++)
		for (int j = 1; j <= n; j++)
		{
			for (int k = 1; k <= n; k++)
				temp.c[i][j] = (temp.c[i][j] + A.c[i][k] * B.c[k][j] % mod)%mod;
		}
	return temp;
}



int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			cin >> A.c[i][j];
	for (int i = 1; i <= n; i++)
		B.c[i][i] = 1;

	while (m>0)
	{
		if (m % 2 == 1)
			B = B * A;
		A = A * A;
		m /= 2;
	}

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
			cout << B.c[i][j] << " ";
		cout << endl;
	}
	return 0;
}

5.进阶运用,蓝桥杯15届省赛c语言组第9题

这题难,自己写不出来,贴个链接垒骰子

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/135361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

S32K144—什么是SBC系统基础芯片?

SBC&#xff08;System Basis Chip&#xff09;芯片在汽车电子领域可谓占一席之地了。那么什么是SBC&#xff1f;怎么用&#xff1f;用在哪里&#xff1f;主要特性&#xff1f; 可以简单理解成&#xff1a;SBC是一类拥有特出功能&#xff08;电源、通信、监控诊断、安全&#…

【附源码】基于fpga的自动售货机(使用三段式状态机实现)

目录 1、VL38 自动贩售机1 题目介绍 思路分析 代码实现 仿真文件 2、VL39 自动贩售机2 题目介绍&#xff1a; 题目分析 代码实现 仿真文件 3、状态机基本知识 1、VL38 自动贩售机1 题目介绍 设计一个自动贩售机&#xff0c;输入货币有三种&#xff0c;为0.5/1/2元&…

嵌入式Linux驱动开发笔记(八)

嵌入式Linux驱动开发笔记&#xff08;八&#xff09; 交叉编译工具说明&#xff1a; 正点原子提供两种交叉编译工具链。这两种交叉编译工具链解释如下图。 我们只需要知道上面的第二种通用的交叉编译器去学习【正点原子】 I.MX6U 嵌入式 Linux 驱动开发指南这本教程。第一种…

lscpu查看cpu信息

$ lscpu Architecture: x86_64 # 架构CPU op-mode(s): 32-bit, 64-bitAddress sizes: 45 bits physical, 48 bits virtualByte Order: Little Endian # 字节序 CPU(s): 2 # 逻辑cpu数On-line CPU(s) list: 0,1 Vendo…

GitHub上 7 个Spring Boot 优质开源项目

前后端分离已经在慢慢走进各公司的技术栈&#xff0c;不少公司都已经切换到这个技术栈上面了。即使贵司目前没有切换到这个技术栈上面&#xff0c;松哥也非常建议大家学习一下前后端分离开发&#xff0c;以免在公司干了两三年&#xff0c;SSH 框架用的滚瓜烂熟&#xff0c;出来…

hcip第四天实验

实验步骤 配置ip 所有设备可以与公网可以通信&#xff0c;在边界路由器上配置缺省指向ISP 配置普通GRE 启OSPF&#xff0c;对于不规则区域使用重发布 优化LSA更新量 R5&#xff1a; [r5]acl 2000 [r5-acl-basic-2000]rule permit source any [r5]int GigabitEthernet…

数据库知识

关系数据库标准语言SQL 写在开头这一章应该把更多的功夫放在实践上面&#xff0c;书中的语句繁杂多样&#xff0c;不亲自写一写是不容易学会的。其次&#xff0c;理论学了那么多&#xff0c;不会有人不想实践敲一下吧[doge]&#xff1f;建议先搞数据更新中的插入数据后再看查询…

【回答问题】ChatGPT上线了!写出coco数据集的图像分类训练和预测函数代码?

写出coco数据集的图像分类训练代码 好的&#xff0c;我会尽力写出图像分类训练代码。首先&#xff0c;你需要准备好 COCO 数据集的图像和标签&#xff0c;并将其转换成适合你模型使用的格式。其次&#xff0c;你需要选择一个图像分类模型&#xff0c;并定义好模型的结构。接下…

【课程太贵,学习无门,让你们了解CSS3入门知识】

文章目录‍❤️‍&#x1f525;CSS简介‍‍‍‍❤️‍&#x1f525;CSS选择器❣️选择器一❣️选择器二❣️关系选择器‍❤️‍&#x1f525;CSS属性❣️字体属性❣️背景属性❣️文本属性❣️表格属性‍❤️‍&#x1f525;CSS文档流‍❤️‍&#x1f525;CSS浮动‍❤️‍&…

【编程导航】设计模式学习笔记

设计模式日常学习(一)设计模式 软件设计模式的概念 软件设计模式&#xff08;Software Design Pattern&#xff09;&#xff0c;又称设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的…

windows下编译dtkwidget

参考 https://blog.csdn.net/yuxue321/article/details/109552210 步骤 安装官方qt5.12.3&#xff0c;安装时勾选64位版本、32位版本 下载glib和pkg&#xff0c;到mingw73_32目录下&#xff0c;解压到当前文件夹 https://brltty.app/archive/Windows/MinGW/glib_2.34.3-1_wi…

【大数据】Hadoop完全分布式配置(超详细)

文章目录概述1.准备Linux2.安装JDK3.克隆两台虚拟机4.免密登陆5.安装Hadoop6.配置Hadoop配置文件7.启动服务8.在集群上测试一个jar包-单词统计的功能问题总结概述 Hadoop完全分布式配置-具体步骤如下 默认前提&#xff1a; 1.在Windows平台下安装Vmware平台&#xff08;默认已…

数据库的三大范式

数据库的三大范式 设计关系数据库时&#xff0c;需要遵从不同的规范要求&#xff0c;设计出合理的关系型数据库&#xff0c;这些不同的规范要求被称为不同的范式&#xff0c;越高的范式数据冗余度越低。 实际开发中涉及到的范式一般有三种&#xff1a;第一范式、第二范式、第…

WindowsTerminal_01 配置SSH连接

文章目录1 前言2 过程参考1 前言 windows terminal 功能强大&#xff0c;可以自定义终端。由于实验需求&#xff0c;需要用到Linux服务器&#xff0c;所以打算使用Windows Termial 来配置终端&#xff0c;以此来方便地登录服务器&#xff0c;执行一些简单的命令 2 过程 自定…

MongoDB基础

目录简介安装基操pymongo简介 MongoDB 是一个非关系型数据库非常适合超大数据集的存储&#xff0c;由 C 语言编写&#xff0c;旨在为 WEB 应用提供可扩展的高性能数据存储解决方案MongoDB 是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰…

TC275——03开发环境搭建

开发环境与工具链的搭配有很多&#xff0c;这里选择最省事的英飞凌自己推出的一款基于eclipse的IDE&#xff0c;主要是学习&#xff0c;不用于商业用途。 安装ADS开发环境 下载网址&#xff1a; AURIX™ Development Studio - Infineon Technologies 下载这个安装包 双击安装…

Springboot-Vue项目框架每部分的介绍

Springboot-Vue项目框架每部分的介绍 文章目录Springboot-Vue项目框架每部分的介绍前端后端前端 后端 如上图所示&#xff0c;在Springboot项目中&#xff0c;目录结构有代码层结构和资源文件的结构 SpringBoot项目框架对工程结构并没有特殊的限制&#xff0c;只要是良好的工程…

C语言--图书管理项目

C语言图书管理系统项目 第一节 C 语言基础以及基本数据类型 第二节 C 语言运算符 第三节 C 语言控制语句 第四节 C 语言自定义函数 第五节 C 语言修饰变量的关键字 第六节 C 语言构造数据类型–数组 第七节 C 语言字符串 第八节 C 语言指针 第九节 指针与函数、指针函数、函数…

【Linux多线程编程】1. 多线程与单线程

什么是单线程 在描述什么是多线程之前&#xff0c;先讲讲什么是单线程。 int var 100; // 全局变量 var&#xff0c;初始值为 100 void func(){var 100;std::cout << "now var is: " << var << std::endl; // c 语法&#xff0c;意思为输出 va…

【强训】day02

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、选择二、 编程1. 排序子序列2. 倒置字符串答案1. 选择2. 编程普通小孩也要热爱生活&#xff01; 一、选择 阅读如下代码。 请问&#xff0c;对语句行 test.hello(). 描述正确的有&#xff08;&#xff09; pa…