vector<vector<int>> op1(vector<vector<int>> mtx, int n, int m) { vector<vector<int>> rotate(m, vector<int>(n)); // ⚠️ m行 n列! for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { rotate[j][n - i - 1] = mtx[i][j]; } } return rotate; }
调用后必须 swap(n, m),因为维度变了。
操作 2:纵向翻折
沿中轴线左右翻转,n 和 m 不变,直接原地交换即可:
1 2 3 4 5 6 7 8
vector<vector<int>> op2(vector<vector<int>> mtx, int n, int m) { for (int i = 0; i < n; i++) { for (int j = 0; j < m / 2; j++) { swap(mtx[i][j], mtx[i][m - j - 1]); // ⚠️ 不是 n-j-1 } } return mtx; }
操作 3:逆时针旋转 90°
不需要推导逆时针公式。逆时针 90° = 顺时针 90° 三次:
1 2 3 4 5 6
vector<vector<int>> op3(vector<vector<int>> mtx, int n, int m) { auto rotate = op1(mtx, n, m); // 顺时针一次 rotate = op1(rotate, m, n); // ⚠️ 传的是 m,n! rotate = op1(rotate, n, m); // ⚠️ 又变回 n,m! return rotate; }
注意每次传给 op1 的 n 和 m 都在交替,因为中间结果矩阵的维度一直在变。
⚠️ 最关键的坑:swap(n, m)
每次执行操作 1 或操作 3 后,n 和 m 必须交换。否则下一步操作的矩阵维度全是错的:
1 2 3 4 5 6 7 8 9 10 11
for (int i = 0; i < k; i++) { if (op[i] == 1) { mtx = op1(mtx, n, m); swap(n, m); // ⚠️ 转后维度交换 } elseif (op[i] == 2) { mtx = op2(mtx, n, m); // 翻折不改变维度 } else { mtx = op3(mtx, n, m); swap(n, m); // ⚠️ 逆时针转也会换维度 } }
vector<vector<int>> op1(vector<vector<int>> mtx, int n, int m) { vector<vector<int>> rotate(m, vector<int>(n)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { rotate[j][n - i - 1] = mtx[i][j]; } } return rotate; }
vector<vector<int>> op2(vector<vector<int>> mtx, int n, int m) { for (int i = 0; i < n; i++) { for (int j = 0; j < m / 2; j++) { int temp = mtx[i][j]; mtx[i][j] = mtx[i][m - j - 1]; mtx[i][m - j - 1] = temp; } } return mtx; }
vector<vector<int>> op3(vector<vector<int>> mtx, int n, int m) { auto rotate = op1(mtx, n, m); rotate = op1(rotate, m, n); rotate = op1(rotate, n, m); return rotate; }
intmain(){ int n, m, k; while (cin >> n >> m >> k) { vector<vector<int>> mtx(n, vector<int>(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> mtx[i][j]; } } vector<int> op(k, 0); for (int i = 0; i < k; i++) cin >> op[i];
for (int i = 0; i < k; i++) { if (op[i] == 1) { mtx = op1(mtx, n, m); swap(n, m); // ⚠️ 顺时针转后维度交换 } elseif (op[i] == 2) { mtx = op2(mtx, n, m); // 翻折不换维度 } else { mtx = op3(mtx, n, m); swap(n, m); // ⚠️ 逆时针转后也要换 } }
for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout << mtx[i][j] << " "; } cout << endl; } } }