第34次CCF-CSP认证考试 第二题 矩阵重塑(其二)【基础篇】
第二题的难度较大,我们还是延续之前的作风,要使用简单,易理解的语句和知识解决,也就是一些基础的知识,不涉及太多算法以及模型,数据结构等。由于题目难度较大,所以解释部分会比较多。下面开始问题分析。
先奉上题目链接:矩阵重塑(其二)
思路
首先,这道题要是使用二维数组的思路很容易超时,尤其是在实现重塑和转置方面,需要多次使用双层for循环来复制二维数组。所以我们的思路跟第一题一样,用将二维矩阵化为一维数组的形式,来提升效率,但在这过程中要解决的问题就比较多了。
第一个问题:查询
首先,我们先来解决查询的问题。大家学过二维数组,应该都知道二维数组转换为一维数组时如何做到一一对应。其实就是我们常说的按行存储或者按列存储,甚至更简单,因为通常我们都是用这个来计算存储地址的,这里换为查找索引,就更加好理解了。
比如:有一个数组A,规模为n*m,即:A[n][m].则它的一维形式为:A1[n*m],那么假设我们要查找的元素是A[a][b],也就是第a+1行的第b+1个元素,那么它对应的当然就是第a*m+b个元素啦,所以在一维数组中,我们直接查找A1[a*m+b]就好了。附上一张讲解图。
第二个问题:转置
之后就是要解决已知二维数组对应的一维数组如何将其进行转置的问题了,这里就需要用到这样一个公式了:A1[(x%m)*n+x/m]=A[x];其中:A1表示转置后的新数组,A表示转置前的原数组。另外,转置过后,矩阵的行和列会发生交换,这点也很重要,不能忽略!!!
第三个问题:重塑
这个问题是最简单的问题,没有太多公式。因为重塑并不会影响一维数组的构造,所有不需要对一维数组进行操作,只需要将重塑后的规模进行保留,然后用新的规模进行第一个问题查找即可。
代码
下面奉上代码:
#include<iostream>
using namespace std;
// 定义全局变量n, m, t,分别表示矩阵的行数、列数和操作次数
int n, m, t;
int main() {
// 从标准输入读取矩阵的行数n、列数m和操作次数t
cin >> n >> m >> t;
// 定义变量n1和m1,用于记录矩阵重塑或转置后的新尺寸
int n1 = n, m1 = m;
// 定义一维数组array,用于存储矩阵的所有元素,大小为n*m
int array[n * m], num = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> array[num++]; // 读取元素并存储到array中,同时递增num
}
}
// 定义变量a, b, op,用于存储操作类型及其参数
int a, b, op;
// 循环t次,执行t个操作
for (int i = 0; i < t; i++) {
cin >> op >> a >> b;
if (op == 1) { // 操作类型1:重塑矩阵
n1 = a; // 更新矩阵的行数为a
m1 = b; // 更新矩阵的列数为b
}
if (op == 2) { // 操作类型2:转置矩阵
int array1[n * m]; // 创建一个临时数组array1,用于存储转置后的矩阵
// 遍历当前矩阵的所有元素,并将它们转置到临时数组array1中
for (int i = 0, x = 0; i < n * m; i++, x++) {
//转置前后的二维矩阵的一维形式符合一定规律:array1[(x%m1)*n1+x/m1]=array[x];
array1[(x % m1) * n1 + x / m1] = array[x];
}
// 将转置后的矩阵复制回array
for (int i = 0; i < n * m; i++) {
array[i] = array1[i];
}
// 交换n1和m1,因为转置后行数和列数互换
int temp = n1;
n1 = m1;
m1 = temp;
}
if (op == 3) { // 操作类型3:查询矩阵元素
// 输出位于第a行,第b列的元素(使用转置后的尺寸计算索引)
cout << array[m1 * a + b] << endl;
}
}
return 0;
}
本文到此结束,希望对小伙伴们有所帮助,阅读时有任何困难欢迎评论区留言或私信我,感谢阅读!