对于一个奇数n阶方阵,请给出经过顺时针方向m次旋转后的结果。
输入格式:
测试数据有多组,处理到文件尾。每组测试的第一行输入2个整数n,m(1<n<20,1≤m≤100),接下来输入n行数据,每行n个整数。
输出格式:
对于每组测试,输出奇数阶方阵经过m次顺时针方向旋转后的结果。每行中各数据之间留一个空格。
输入样例:
3 2
4 9 2
3 5 7
8 1 6
3 1
4 9 2
3 5 7
8 1 6
3 7
4 9 2
3 5 7
8 1 6
3 8
4 9 2
3 5 7
8 1 6
输出样例:
6 1 8
7 5 3
2 9 4
8 3 4
1 5 9
6 7 2
2 7 6
9 5 1
4 3 8
4 9 2
3 5 7
8 1 6
来源:
[1] 黄龙军, 等. 大学生程序设计竞赛入门—C/C++程序设计(微课视频版), 北京:清华大学出版社, 2020.11. ISBN:9787302564744
[2] 黄龙军.程序设计竞赛入门(Python版),北京:清华大学出版社,2021.4. ISBN:9787302571230
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
思路
主函数
- 使用
while
循环处理多组测试数据,直到输入结束为止。 - 每次读入两个整数
n
和m
,分别表示方阵的行列数和要旋转的次数。 - 声明二维数组
a
存储方阵中的元素。使用双重循环依次读入每个元素,存储到数组a
中。 - 调用函数
rotate()
执行顺时针旋转操作。函数接受三个参数:数组a
、方阵的行列数n
和要旋转的次数m
。 - 遍历数组
a
,输出旋转后的结果。
rotate()函数
- 首先,外层循环
for (k = 0; k < m; k++)
表示需要旋转的次数。每一次旋转操作都会将二维数组顺时针方向旋转 90 度。 - 然后,我们遍历二维数组中的每个子区间。对于一个 n × n 的方阵,我们可以分为 n/2 个子区间,每个子区间由四个位置组成,即左上角、右上角、右下角和左下角。
- 对于每个子区间,我们使用三重循环依次交换四个位置的值。具体地,内部的两重循环用于遍历子区间中的元素,第三重循环是为了执行交换操作。其中,变量
i
和j
分别表示二维数组中的行和列,变量t
是一个临时变量,用于存储要交换的两个元素的值。 - 交换操作如下:
- 首先,将左上角的元素
a[i][j]
存储到变量t
中。 - 然后,将右上角的元素
a[n-j-1][i]
移动到左上角的位置a[i][j]
上。注意,这里的n-j-1
表示列数为 j 的元素在旋转后的位置,即原来的倒数第 j 行。 - 接着,将右下角的元素
a[n-i-1][n-j-1]
移动到右上角的位置a[n-j-1][i]
上。注意,这里的n-i-1
表示行数为 i 的元素在旋转后的位置,即原来的倒数第 i 列;n-j-1
表示列数为 j 的元素在旋转后的位置,即原来的倒数第 j 行。 - 然后,将左下角的元素
a[j][n-i-1]
移动到右下角的位置a[n-i-1][n-j-1]
上。注意,这里的j
表示列数为 j 的元素在旋转后的位置,即原来的第 j 行;n-i-1
表示行数为 i 的元素在旋转后的位置,即原来的倒数第 i 列。 - 最后,将变量
t
中存储的左上角元素的值赋给左下角的位置a[j][n-i-1]
上。
- 首先,将左上角的元素
经过 m 次循环后,方阵中的元素就完成了顺时针旋转操作。
代码
#include <stdio.h>
void rotate(int a[][20], int n, int m)
{
int i, j, k, t;
for (k = 0; k < m; k++) { // 循环执行 m 次旋转操作
for (i = 0; i < n / 2; i++) { // 遍历每个子区间
for (j = i; j < n - i - 1; j++) { // 交换子区间中的四个元素
t = a[i][j]; // 存储左上角的元素
a[i][j] = a[n - j - 1][i]; // 将右上角的元素移到左上角
a[n - j - 1][i] = a[n - i - 1][n - j - 1]; // 将右下角的元素移到右上角
a[n - i - 1][n - j - 1] = a[j][n - i - 1]; // 将左下角的元素移到右下角
a[j][n - i - 1] = t; // 将存储在变量 t 中的左上角元素赋值到左下角
}
}
}
}
int main()
{
int n, m, a[20][20];
while (scanf("%d%d", &n, &m) != EOF) { // 处理多组测试数据
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &a[i][j]); // 读入每个元素
}
}
rotate(a, n, m); // 执行旋转操作
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%d", a[i][j]); // 输出二维数组中的每个元素
if (j == n - 1) { // 如果是该行的最后一个元素,输出换行符
printf("\n");
} else { // 否则,输出空格
printf(" ");
}
}
}
}
return 0;
}