CCFCSP第34次认证第一题——矩阵重塑(其一)
第34次认证第一题——矩阵重塑(其一)
官网链接
时间限制: 1.0 秒
空间限制: 512 MiB
相关文件: 题目目录(样例文件)
题目背景
矩阵(二维)的重塑(reshape)操作是指改变矩阵的行数和列数,同时保持矩阵中元素的总数不变。
题目描述
矩阵的重塑操作可以具体定义为以下步骤:
设原矩阵为 𝑀M,其维度为 n×m,即有 n 行和 m 列。新矩阵为 M′,其维度为 p×q。重塑操作要满足 n×m=p×q,这保证了元素的总数不变。
-
线性化原矩阵:按照行优先的顺序,将原矩阵 M 的元素转换成一个长度为 n×m 的一维数组 A。这意味着你先读取 M 的第 0 行元素,然后是第 1 行,依此类推,直到最后一行。
-
填充新矩阵:使用一维数组 A 中的元素按照行优先的顺序填充新矩阵 M′。首先填充 M′ 的第 0 行,直到该行有 q 个元素,然后继续填充第 1 行,直到所有 p 行都被填满。
给定原矩阵中的一个元素的位置 (i,j)(0≤i<n 且 0≤j<m),我们可以找到这个元素在被线性化后的一维数组 A 中的位置 k(0≤k<n×m),然后确定它在新矩阵 M′ 中的位置 (i′,j′)(0≤i′<p 且 0≤j<q)。它们之间满足如下数学关系:i×m+j=k=i′×q+j′
给定 n×m 的矩阵 𝑀M 和目标形状 p、q,试将 M 重塑为 p×q 的矩阵 M′。
输入格式
从标准输入读入数据。
输入共 n+1 行。
输入的第一行包含四个正整数 n、m 和 p、q。
接下来依次输入原矩阵 M 的第 0 到第 n−1 行,每行包含 m 个整数,按列下标从 0 到 m−1 的顺序依次给出。
输出格式
输出到标准输出。
输出共 p 行,每行 q 个整数,表示重塑后的矩阵 M′。输出格式与输入相同,即依次输出 M′ 的第 0 行到第 p−1 行;行内按列下标从 0 到 q−1 的顺序输出,且两个整数间仅用一个空格分隔。
样例1输入
2 3 3 2
1 2 3
4 5 6
样例1输出
1 2
3 4
5 6
样例2输入
2 2 1 4
6 6
6 6
样例2输出
6 6 6 6
子任务
全部的测试数据满足:
-
n、m 和 p、q 均为正整数且 n×m=p×q≤104;
-
输入矩阵中每个元素的绝对值不超过 1000。
提示
评测环境仅提供各语言的标准库,特别地,不提供任何线性代数库(如 numpy
、pytorch
等)。
语言和编译选项
# | 名称 | 编译器 | 额外参数 | 代码长度限制 |
---|---|---|---|---|
0 | g++ | g++ | -O2 -DONLINE_JUDGE | 65536 B |
1 | gcc | gcc | -O2 -DONLINE_JUDGE | 65536 B |
2 | java | javac | 65536 B | |
3 | python3 | python3 | 65536 B |
参考题解
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int main(){
int row1, col1, row2, col2;
cin >> row1 >> col1 >> row2 >> col2;
int data[row1 * col1];
memset(data, 0, sizeof(data));
for(int i = 0; i < row1 * col1; i++){
cin >> data[i];
}
// int result[row2][col2];----------不需要用数组存结果,直接输出就好了
/*-----!!还可以进一步优化空间效率,不需要将数据读入数组,直接边读入边输出即可(不过这个是对于考试来说,自己调试的话不太方便看结果)
for(int i = 0; i < row2; i++){
for(int j = 0; j < col2; j++){
int value;
cin >> value;
cout << value << " ";
}
cout << endl;
}
-----------------------*/
// memset(result, 0, sizeof(result));
int index = 0;
for(int i = 0; i < row2; i++){
for(int j = 0; j < col2; j++){
cout << data[index] << " ";
index++;
}
cout << endl;
}
return 0;
}
优化后
完成矩阵重塑(其二)后受到的优化启发
矩阵重塑(其二)
#include <iostream>
#include <vector>
using namespace std;
int main () {
int n1, m1, n2, m2;
// cin >> n1 >> m1 >> n2 >> m2;
scanf("%d%d%d%d", &n1, &m1, &n2, &m2); //不能用%D,没有定义这种行为,虽然不会报错,但是赋值并未成功
vector<int> data (n1 * m1);
for (int i = 0; i < n1 * m1; i++) {
// cin >> data[i];
scanf("%d", &data[i]);
}
for (int i = 0; i < n2; i++) {
for (int j = 0; j < m2; j++) {
// cout << data [i * m2 + j] << " ";
printf("%d ", data [i * m2 + j]);
}
// cout << "\n";
printf("\n");
}
return 0;
}
小结
本题较为简单,用时10分钟左右,不过不知道还有没有小坑,重点是无需存储直接输出的思想,可以提高效率。
一般来说第一题较简单,可以先看输入输出,看不明白再去看题目。