📌  相关文章
📜  国际空间研究组织 | ISRO CS 2018 |问题 77(1)

📅  最后修改于: 2023-12-03 15:37:16.114000             🧑  作者: Mango

国际空间研究组织 | ISRO CS 2018 |问题 77

这道题目是一个编程问题,测试代码的语言是C++,需要实现一个函数matrixRotation来旋转矩阵。

问题描述

给定一个mn列的矩阵matrix以及一个整数r,定义一个“旋转”的操作是将矩阵的每一个元素按照顺时针方向依次替换,如下图所示:

matrix_rotation_image

现在要求将矩阵顺时针方向旋转r次,返回旋转后的矩阵。

注意:

  • r是非负整数,可以大于mn
  • mn的范围均不超过300
  • 矩阵中元素的值的范围均为int类型
函数签名
void matrixRotation(vector<vector<int>> matrix, int m, int n, int r) 
样例
样例1

输入

vector<vector<int>> matrix{{1, 2, 3, 4}, {7, 8, 9, 10}, {13, 14, 15, 16}, {19, 20, 21, 22}, {25, 26, 27, 28}};
int m = matrix.size();
int n = matrix[0].size();
int r = 7;
matrixRotation(matrix, m, n, r);

输出

28 27 26 25
22  9 15 19
16  8 21 13
10 14 20  7
 4  3  2  1
样例2

输入

vector<vector<int>> matrix{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int m = matrix.size();
int n = matrix[0].size();
int r = 2;
matrixRotation(matrix, m, n, r);

输出

3  6  9
2  5  8
1  4  7
解决思路

本题解决思路是模拟,按照左上角到右下角的顺序依次旋转矩阵,旋转完一圈后,再进行下一圈。

旋转的过程中需要使用另外一个矩阵res来存储旋转后的结果,再将结果复制回原来的矩阵中。

需要注意的是,旋转一圈时,需要对r取模,因为当旋转次数为矩阵某一个边长时,相当于不用旋转,因此需要模操作。

代码
void matrixRotation(vector<vector<int>> matrix, int m, int n, int r) {
    int min_mn = min(m, n);
    vector<vector<int>> res(m, vector<int>(n, 0));
    for (int i = 0; i < min_mn / 2; i++) {
        int width = n - 2 * i - 1;
        int height = m - 2 * i - 1;
        int num_elems_in_cycle = 2 * width + 2 * height;
        int shift = r % num_elems_in_cycle;
        int row = i;
        int col = i;
        for (int j = 0; j < num_elems_in_cycle; j++) {
            int diff = j - shift;
            int new_row = row, new_col = col;
            if (diff >= 0 && diff < width) {
                new_col = col + diff;
            } else if (diff >= width && diff < width + height) {
                new_row = row + diff - width;
                new_col = col + width;
            } else if (diff >= width + height && diff < 2 * width + height) {
                new_row = row + height;
                new_col = col + 2 * width + height - diff;
            } else if (diff >= 2 * width + height && diff < num_elems_in_cycle) {
                new_row = row + num_elems_in_cycle - diff;
                new_col = col;
            }
            res[new_row][new_col] = matrix[row][col];
            // move to new position
            if (diff == num_elems_in_cycle - 1) {
                break;
            } else if (diff >= 0 && diff < width) {
                col++;
            } else if (diff >= width && diff < width + height) {
                row++;
            } else if (diff >= width + height && diff < 2 * width + height) {
                col--;
            } else if (diff >= 2 * width + height && diff < num_elems_in_cycle) {
                row--;
            }
        }
    }
    // copy back
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            matrix[i][j] = res[i][j];
        }
    }
}