图像旋转

按原矩阵从右到左的列顺序逐列输出,完成逆时针旋转 90 度。

OJ: shumeng

题目 ID: CSP201503A

难度:入门

标签:模拟二维数组

日期: 2026-07-31 16:21

形式化题目

给定一个 n×mn\times m 的矩阵,将其逆时针旋转 9090^\circ,输出旋转后 m×nm\times n 的矩阵。

思路

先看显式构造旋转后矩阵的写法:

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-31 16:21
 * update_at: 2026-08-17 22:50
 */
// brute.cpp:小数据基准,显式构造旋转后的矩阵。
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    vector<vector<int> > image(n, vector<int>(m));
    vector<vector<int> > rotated(m, vector<int>(n));
    for (int row = 0; row < n; row++) {
        for (int column = 0; column < m; column++) {
            cin >> image[row][column];
            rotated[m - 1 - column][row] = image[row][column];
        }
    }

    for (int row = 0; row < m; row++) {
        for (int column = 0; column < n; column++) {
            if (column > 0) cout << ' ';
            cout << rotated[row][column];
        }
        cout << '\n';
    }

    return 0;
}

brute.cpp 里用一个新矩阵记录旋转结果:原矩阵 (row,column)(row, column) 的元素移动到旋转后矩阵的 (m1column,row)(m-1-column, row) 位置,最后按行输出。这个版本最贴近直觉,适合作为小数据基准。

关键观察:逆时针旋转 9090^\circ 后,答案的每一行恰好对应原矩阵的某一列

  • 原矩阵的最右列成为答案的第一行;
  • 列内从上到下的顺序保持不变。

因此不需要真的移动元素,读入原矩阵后,让列号从 m-1 降到 0,每一列按行号从 0n-1 输出即可。

代码

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-31 16:21
 * update_at: 2026-08-17 22:50
 */
#include <bits/stdc++.h>
using namespace std;

int image[1005][1005]; // 原始图像矩阵

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    for (int row = 0; row < n; row++) {
        for (int column = 0; column < m; column++) {
            cin >> image[row][column];
        }
    }

    // 原矩阵从最右列到最左列依次成为旋转后的每一行。
    for (int column = m - 1; column >= 0; column--) {
        for (int row = 0; row < n; row++) {
            if (row > 0) cout << ' ';
            cout << image[row][column];
        }
        cout << '\n';
    }

    return 0;
}

复杂度

  • 时间:每个元素只输出一次,O(nm)O(nm)
  • 空间:存储原矩阵,O(nm)O(nm)

总结

矩阵旋转不必移动元素,只要确定“输出的一行来自原矩阵的哪一列”。逆时针旋转就是从右到左依次读取原矩阵的各列,本题是这类坐标映射模拟题的起点。