题目出自 APCS 网站 > 试题範例 > 2016-03-05_实作题 > 第二题 成绩指标
连结
解答仅供参考
解答:
#include <stdio.h>#include <stdlib.h>//翻转矩阵//matrix : 矩阵//currentIndex : 矩阵当前位置//size : 矩阵最大边长//size_x : 矩阵 x 轴长度//size_y : 矩阵 y 轴长度void TurnOver(int *matrix, int currentIndex, int size, int size_x, int size_y){ int _currentIndex = 1 - currentIndex; int _i, _j; for (int i = 0; i < size_x; i++) { for (int j = 0; j < size_y; j++) { _i = size_x - i - 1; _j = j; *(matrix + _currentIndex * size * size + _i * size + _j) = *(matrix + currentIndex * size * size + i * size + j); } }}//旋转矩阵//matrix : 矩阵//currentIndex : 矩阵当前位置//size : 矩阵最大边长//size_x : 矩阵 x 轴长度//size_y : 矩阵 y 轴长度void Rotate(int *matrix, int currentIndex, int size, int size_x, int size_y){ int _currentIndex = 1 - currentIndex; int _i, _j; for (int i = 0; i < size_x; i++) { for (int j = 0; j < size_y; j++) { _i = j; _j = size_x - i - 1; *(matrix + _currentIndex * size * size + _i * size + _j) = *(matrix + currentIndex * size * size + i * size + j); } }}int main(void){ int r, c, m; scanf("%d %d %d", &r, &c, &m); //取得最大边长 int size = r > c ? r : c; int matrix[2][size][size]; //当前矩阵位置 int currentIndex = 0; //读取矩阵 for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { scanf("%d", &matrix[currentIndex][i][j]); } } //读取操作 int operate[m]; for (int i = 0; i < m; i++) { scanf("%d", &operate[i]); } //操作矩阵 for (int i = 0; i < m; i++) { if (operate[i] == 1) { //翻转 TurnOver(&matrix[0][0][0], currentIndex, size, r, c); } else { //旋转 Rotate(&matrix[0][0][0], currentIndex, size, r, c); //旋转后对调边长 r = r ^ c; c = r ^ c; r = r ^ c; } //切换当前矩阵 currentIndex = 1 - currentIndex; } //印出结果 printf("%d %d\n", r, c); for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { printf("%d", matrix[currentIndex][i][j]); if (j < c - 1) { printf(" "); } } printf("\n"); } system("pause"); return 0;}
输入:
3 2 31 13 11 21 0 0
3 2 23 3 2 11 20 1
输出:
3 21 11 32 1
2 32 1 31 2 3
说明:
程式内使用两个矩阵来做搬移动作,每次翻转
和旋转
都会把旧矩阵的值移动到新矩阵,在使用 currentIndex
来记录当前的新矩阵。
翻转:
翻转的逻辑比较简单,只要找出矩阵要对调的上下两座标,然后将里面的值对调就可以完成翻转。
//_i 为新的 x 轴座标//_j 为新的 y 轴座标int _i, _j;for (int i = 0; i < size_x; i++){ for (int j = 0; j < size_y; j++) { _i = size_x - i - 1; _j = j; //... //移动位置 //... }}
旋转:
旋转比较难想一点,可以在纸上把座标画出来比较好找规律。
旋转前后的座标
A (0,0) => (0,2)B (1,0) => (0,1)C (2,0) => (0,2)D (0,1) => (1,2)E (1,1) => (1,1)F (2,1) => (1,0)
从上面的结果可以看出,
旋转后的 x 轴座标
等于转换前的 y 轴座标
,
旋转后的 y 轴座标
等于 x 轴边长
减去 x 轴座标
再减一。
//_i 为新的 x 轴座标//_j 为新的 y 轴座标int _i, _j;for (int i = 0; i < size_x; i++){ for (int j = 0; j < size_y; j++) { _i = j; _j = size_x - i - 1; //... //移动位置 //... }}
相关文章:
[C++][APCS] 成绩指标
[C++][APCS] 矩阵转换