1 条题解

  • 0
    @ 2025-4-7 16:47:00

    一、题意分析

    背景与目标 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
    上传者