编写程序实现将m行n列的矩阵最外围元素旋转k步,当k大于0顺时针旋转,k小于0则逆时针旋转。要求:在主函数中将数字1到m*n按由左至右、由上到下的顺序填入矩阵中;在主函数中调用fun函数实现对矩阵的旋转;在主函数中输出旋转后的矩阵内容。(m和n均不大于20)
时间: 2025-06-23 12:27:22 浏览: 14
### 实现矩阵最外层元素旋转
为了实现一个 `m` 行 `n` 列的矩阵并对其最外层元素进行顺时针或逆时针旋转,可以通过以下方法来处理:
#### 初始化矩阵
首先定义一个函数用于初始化指定大小的矩阵,并填充初始数据。
```cpp
#include <iostream>
#include <vector>
using namespace std;
// 函数:初始化 m*n 矩阵
void initializeMatrix(vector<vector<int>>& matrix, int rows, int cols) {
for (int i = 0; i < rows; ++i) {
vector<int> row(cols);
for (int j = 0; j < cols; ++j) {
row[j] = i * cols + j + 1;
}
matrix.push_back(row);
}
}
```
#### 执行旋转操作
对于给定步数 k 来说,当 k 是正数时表示顺时针方向;如果是负数,则代表逆时针方向。这里采用了一种优化的方法来进行旋转,即通过三次翻转的方式来代替逐个移动元素的方式[^1]。
```cpp
// 获取当前层数边界范围内的元素数量
int getLayerSize(const vector<vector<int>>& matrix, int layer) {
int rows = matrix.size();
int cols = matrix[0].size();
if ((rows - 2 * layer <= 1 && cols - 2 * layer <= 1)) return 0;
// 上边和下边各一层加上左边右边去掉四个角重复计算的部分
return 2 * (cols - 2 * layer) + 2 * (rows - 2 * layer - 2);
}
// 反转特定位置上的元素序列
void reverseElements(vector<vector<int>>& matrix, int startRow, int endRow,
int startCol, int endCol) {
while (startRow < endRow || startCol < endCol) {
swap(matrix[startRow][startCol], matrix[endRow][endCol]);
if (++startCol >= endCol--) break;
if (--endRow <= startRow++) break;
}
}
// 对于单圈的情况单独处理
void rotateSingleCircle(vector<vector<int>>& matrix, int& offset, bool clockwise) {
const int size = matrix.size() * matrix[0].size();
for (int i = 0; i < abs(offset); ++i){
if(clockwise){
// 将最后一个元素移到第一个位置
int lastValue = matrix[matrix.size()-1][matrix[0].size()-1];
for(int r=matrix.size()-1;r>=0;--r){
for(int c=matrix[r].size()-1;c>0;--c){
matrix[r][c]=matrix[r][c-1];
}
if(r!=0){
matrix[r][0]=matrix[r-1][matrix[r-1].size()-1];
}else{
matrix[r][0]=lastValue;
}
}
} else {
// 将第一个元素移到最后的位置
int firstValue = matrix[0][0];
for(int r=0;r<matrix.size();++r){
for(int c=0;c<matrix[r].size()-1;++c){
matrix[r][c]=matrix[r][c+1];
}
if(r!=(matrix.size()-1)){
matrix[r][matrix[r].size()-1]=matrix[r+1][0];
}else{
matrix[r][matrix[r].size()-1]=firstValue;
}
}
}
}
}
// 主要逻辑:根据偏移量调整最外围一圈的数据
void adjustOutermostRing(vector<vector<int>>& matrix, int offset) {
int layers = min(matrix.size(), matrix[0].size()) / 2;
for (int l = 0; l < layers; ++l) {
int elementsToMove = getLayerSize(matrix, l);
if(elementsToMove==0){continue;}
// 计算实际需要移动的距离
int actualShiftsNeeded = abs(offset % elementsToMove);
if(actualShiftsNeeded == 0){ continue; }
if(abs(offset)==elementsToMove){
rotateSingleCircle(matrix,offset,(offset>0));
continue;
}
// 如果是逆向则先整体反序再做相应位移变换
if (offset < 0) {
reverseElements(matrix, l, matrix.size() - l - 1,
l, matrix[l].size() - l - 1);
offset *= -1;
}
// 进行部分区域反转达到效果
reverseElements(matrix, l, l + actualShiftsNeeded - 1,
l, l + actualShiftsNeeded - 1);
reverseElements(matrix, l + actualShiftsNeeded, matrix.size() - l - 1,
l + actualShiftsNeeded, matrix[l].size() - l - 1);
reverseElements(matrix, l, matrix.size() - l - 1,
l, matrix[l].size() - l - 1);
}
}
```
#### 展示最终结果
最后提供一个简单的打印功能以便查看修改后的矩阵状态。
```cpp
// 显示矩阵内容
void displayMatrix(const vector<vector<int>>& matrix) {
cout << "Matrix:" << endl;
for (const auto& row : matrix) {
for (const auto& elem : row) {
printf("%3d ", elem);
}
puts("");
}
}
```
#### 完整流程测试案例
下面是一个完整的例子用来验证上述算法的有效性。
```cpp
int main(){
int m,n,k;
cin>>m>>n>>k;
vector<vector<int>> mat;
initializeMatrix(mat,m,n);
cout<<"Original Matrix:"<<endl;
displayMatrix(mat);
adjustOutermostRing(mat,k);
cout<<"\nRotated Matrix:"<<endl;
displayMatrix(mat);
return 0;
}
```
此代码实现了对任意尺寸矩形矩阵中最外部环路按指定次数沿不同方向转动的效果。注意这里的输入参数分别为矩阵的高度、宽度以及期望旋转的角度(正值为顺时针,负值为逆时针)。
阅读全文