【2025年莆田市第五期C++专项第三轮选拔真题(初中组)】矩阵转换
题目描述
有一个 n n n 行 m m m 列的矩阵 a i , j a_{i,j} ai,j,你拥有 4 4 4 种技能对矩阵进行操作:
- 技能 1 1 1:将矩阵顺时针旋转 90 90 90 度;
- 技能 2 2 2:将矩阵逆时针旋转 90 90 90 度;
- 技能 3 3 3:将矩阵上下对称翻转;
- 技能 4 4 4:将矩阵左右对称翻转。
现在要对矩阵进行 t t t 次操作,请输出最终矩阵的状态。
输入格式
第一行,三个整数 n , m , t n,m,t n,m,t,表示对 n n n 行 m m m 列的矩阵进行 t t t 次操作;
接下来 n n n 行,每行 m m m 个整数,表示矩阵的初始状态;
接下来 t t t 行,每行一个整数 q q q,表示对矩阵使用的技能。
输出格式
经过 t t t 次操作后的矩阵状态( n n n 行 m m m 列或 m m m 行 n n n 列),同一行中每两个数之间用一个空格隔开。
样例
2 3 4
1 2 3
4 5 6
1
2
3
4
6 5 4
3 2 1
【样例 1 1 1 解释】
共 4 4 4 次操作:
第一次操作,执行技能 1 1 1(将矩阵顺时针旋转 90 90 90 度)后,矩阵如下:
4 1
5 2
6 3
第二次操作,执行技能 2 2 2(将矩阵逆时针旋转 90 90 90 度)后,矩阵如下:
1 2 3
4 5 6
第三次操作,执行技能 3 3 3(将矩阵上下对称翻转)后,矩阵如下:
4 5 6
1 2 3
第四次操作,执行技能 4 4 4(将矩阵左右对称翻转)后,矩阵如下:
6 5 4
3 2 1
2 3 4
1 2 3
4 5 6
1
3
2
4
1 2 3
4 5 6
【样例 2 2 2 解释】
共 4 4 4 次操作:
第一次操作,执行技能 1 1 1(将矩阵顺时针旋转 90 90 90 度)后,矩阵如下:
4 1
5 2
6 3
第二次操作,执行技能 3 3 3(将矩阵上下对称翻转)后,矩阵如下:
6 3
5 2
4 1
第三次操作,执行技能 2 2 2(将矩阵逆时针旋转 90 90 90 度)后,矩阵如下:
3 2 1
6 5 4
第四次操作,执行技能 4 4 4(将矩阵左右对称翻转)后,矩阵如下:
1 2 3
4 5 6
数据范围
对于 20 % 20 \% 20% 的数据, 3 ≤ q ≤ 4 3 \le q \le 4 3≤q≤4;
对于 50 % 50 \% 50% 的数据, 1 ≤ n , m , t ≤ 100 1 \le n,m,t \le 100 1≤n,m,t≤100;
对于 100 % 100\% 100% 的数据, 1 ≤ n , m ≤ 1000 1 \le n,m \le 1000 1≤n,m≤1000, 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104, 1 ≤ q ≤ 4 1 \le q \le 4 1≤q≤4, 0 ≤ a i , j ≤ 1 0 4 0 \le a_{i,j} \le 10^4 0≤ai,j≤104。
问题重述
给定一个n×m的矩阵,需要进行t次操作,每次操作可以是四种变换之一。要求输出最终矩阵状态。
解题思路
直接模拟每次操作会导致时间复杂度过高,特别是当t很大时(如1e4次)。我们采用状态跟踪的方法:
- 旋转状态:用0-3表示0度、90度、180度、270度旋转
- 翻转状态:用布尔值表示是否翻转
- 操作影响:
- 旋转操作只改变旋转状态
- 翻转操作会改变翻转状态并可能影响旋转状态
代码实现
#include <bits/stdc++.h>
using namespace std;
int n, m, t;
int matrix[1005][1005];
int temp[1005][1005];
// 上下翻转
void flipVertical() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m / 2; j++) {
swap(matrix[i][j], matrix[i][m - j + 1]);
}
}
}
// 顺时针旋转90度
void rotateClockwise() {
swap(n, m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
temp[i][j] = matrix[m - j + 1][i];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
matrix[i][j] = temp[i][j];
}
}
}
int main() {
cin >> n >> m >> t;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> matrix[i][j];
}
}
int rotation = 0; // 0: 0度, 1: 90度, 2: 180度, 3: 270度
bool isFlipped = false;
while (t--) {
int op;
cin >> op;
if (op == 1) {
// 顺时针旋转90度
rotation = (rotation + 1) % 4;
} else if (op == 2) {
// 逆时针旋转90度
rotation = (rotation + 3) % 4;
} else if (op == 3) {
// 上下翻转
isFlipped = !isFlipped;
if (rotation % 2 == 0) {
rotation = (rotation + 2) % 4;
}
} else if (op == 4) {
// 左右翻转
isFlipped = !isFlipped;
if (rotation % 2 == 1) {
rotation = (rotation + 2) % 4;
}
}
}
// 应用翻转
if (isFlipped) {
flipVertical();
}
// 应用旋转
while (rotation--) {
rotateClockwise();
}
// 输出结果
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cout << matrix[i][j] << " ";
}
cout << "\n";
}
return 0;
}
复杂度分析
- 时间复杂度:O(nm + t)
- 输入矩阵:O(nm)
- 处理t次操作:O(t)
- 最终变换:O(nm)
- 空间复杂度:O(nm)