1 条题解
-
0
一、题意分析
背景与目标 Sam 和 Sally 设计了一个名为 “shake, rattle and roll” 的加密方案用于发送秘密消息,现在需要编写一个计算机程序来实现该加密方案。
输入说明 输入包含一个或多个加密问题,每个问题占两行: 第一行是加密密钥,以两位数的矩阵大小开头(00 表示 100),范围是 3x3 到 100x100 的正方形矩阵,后面跟着一系列任意顺序的 S、R 或 L 字符。S 代表 “shake” 操作,R 代表 “rattle” 操作,L 代表 “roll” 操作。加密密钥长度限制为 80 个字符。 第二行是要加密的文本消息,消息长度限制为 10000 个字符,且假设消息能完全放入指定的矩阵中。
加密操作 Shake 操作:每个奇数列向上移动一个字符,最上面的字符移动到该列的底部;每个偶数列向下移动一个字符,最底部的字符移动到列的顶部。列从 1 开始编号。 Rattle 操作:每个奇数行向右移动一个字符,最右边的字符移动到同一行中最左边的列;每个偶数行向左移动一个字符,最左边的字符移动到同一行中最右边的列。行从顶部开始编号。 Roll 操作:矩阵周围的每个奇数 “loop” 向右旋转一个字符,而每个偶数 “loop” 向左旋转一个字符。“Loops” 的奇偶性基于其最顶端行的行号(顶行是第 1 行)。
填充规则 如果输入的消息长度小于矩阵的大小,空单元格将用大写字母 A - Z 依次填充,可重复使用。
输出要求 输出加密后的文本,其长度等于矩阵的平方大小(例如,一个 3x3 矩阵产生一个长度为 9 的字符串)。
二、解题思路
数据存储 使用一个二维字符数组 matrix[110][110] 来存储矩阵,将输入的消息按行主序放入矩阵中。
消息填充 根据输入的矩阵大小,将消息放入矩阵。若消息长度小于矩阵大小,用大写字母 A - Z 依次填充剩余的单元格。
加密操作实现 Shake 操作:遍历每一列,根据列的奇偶性进行向上或向下的移动操作。 Rattle 操作:遍历每一行,根据行的奇偶性进行向左或向右的移动操作。 Roll 操作:类似于蛇形填数,对矩阵的每一个 “loop” 进行顺时针或逆时针的旋转操作,根据 “loop” 的奇偶性决定旋转方向。
加密操作执行 根据加密密钥中的字符顺序,依次执行相应的加密操作。
输出结果 将加密后的矩阵按行主序输出,所有字符转换为大写。
参考代码
#include <iostream> #include <cstring> #include <cctype> #include <algorithm> using namespace std; char matrix[100][100]; int n; void fillMatrix(const char* message) { int len = strlen(message); int index = 0; char fill_char = 'A'; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (index < len) { matrix[i][j] = toupper(message[index++]); } else { matrix[i][j] = fill_char++; if (fill_char > 'Z') fill_char = 'A'; } } } } void shake() { for (int j = 0; j < n; j++) { if ((j+1) % 2 == 1) { // Odd column (1-based) char temp = matrix[0][j]; for (int i = 0; i < n-1; i++) { matrix[i][j] = matrix[i+1][j]; } matrix[n-1][j] = temp; } else { // Even column char temp = matrix[n-1][j]; for (int i = n-1; i > 0; i--) { matrix[i][j] = matrix[i-1][j]; } matrix[0][j] = temp; } } } void rattle() { for (int i = 0; i < n; i++) { if ((i+1) % 2 == 1) { // Odd row (1-based) char temp = matrix[i][n-1]; for (int j = n-1; j > 0; j--) { matrix[i][j] = matrix[i][j-1]; } matrix[i][0] = temp; } else { // Even row char temp = matrix[i][0]; for (int j = 0; j < n-1; j++) { matrix[i][j] = matrix[i][j+1]; } matrix[i][n-1] = temp; } } } void roll() { for (int loop = 0; loop < n/2; loop++) { if ((loop+1) % 2 == 1) { // Odd loop (1-based) - rotate right char temp = matrix[loop][loop]; // Top row for (int j = loop; j < n-1-loop; j++) { matrix[loop][j] = matrix[loop][j+1]; } // Right column for (int i = loop; i < n-1-loop; i++) { matrix[i][n-1-loop] = matrix[i+1][n-1-loop]; } // Bottom row for (int j = n-1-loop; j > loop; j--) { matrix[n-1-loop][j] = matrix[n-1-loop][j-1]; } // Left column for (int i = n-1-loop; i > loop+1; i--) { matrix[i][loop] = matrix[i-1][loop]; } matrix[loop+1][loop] = temp; } else { // Even loop - rotate left char temp = matrix[loop][loop]; // Left column for (int i = loop; i < n-1-loop; i++) { matrix[i][loop] = matrix[i+1][loop]; } // Bottom row for (int j = loop; j < n-1-loop; j++) { matrix[n-1-loop][j] = matrix[n-1-loop][j+1]; } // Right column for (int i = n-1-loop; i > loop; i--) { matrix[i][n-1-loop] = matrix[i-1][n-1-loop]; } // Top row for (int j = n-1-loop; j > loop+1; j--) { matrix[loop][j] = matrix[loop][j-1]; } matrix[loop][loop+1] = temp; } } } void encrypt(const char* key, const char* message) { // Parse matrix size n = (key[0]-'0')*10 + (key[1]-'0'); if (n == 0) n = 100; // Fill matrix with message and padding fillMatrix(message); // Process each operation in the key for (int i = 2; key[i] != '\0'; i++) { switch (key[i]) { case 'S': shake(); break; case 'R': rattle(); break; case 'L': roll(); break; } } // Output the encrypted message for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << matrix[i][j]; } } cout << endl; } int main() { char key[100]; char message[10010]; while (cin >> key) { cin.ignore(); // Ignore newline cin.getline(message, 10010); encrypt(key, message); } return 0; }
- 1
信息
- ID
- 1318
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者