文章

【GESP】C++三级练习 luogu-B2116 加密的病历单

GESP三级练习,字符串练习(C++三级大纲中6号知识点,字符串),难度★★☆☆☆。

luogu-B2116 加密的病历单

题目要求

题目描述

小英是药学专业大三的学生,暑假期间获得了去医院药房实习的机会。

在药房实习期间,小英扎实的专业基础获得了医生的一致好评,得知小英在计算概论中取得过好成绩后,主任又额外交给她一项任务,解密抗战时期被加密过的一些伤员的名单。

经过研究,小英发现了如下加密规律(括号中是一个“原文 → 密文”的例子)

  1. 原文中所有的字符都在字母表中被循环左移了三个位置($\text{bcd} \to \text{yza}$)

  2. 逆序存储($\text{abcd} \to \text{dcba}$)

  3. 大小写反转($\text{abXY} \to \text{ABxy}$)

现在给出一个加密的字符串,请你将其解密

输入格式

一个加密的字符串。(长度小于 $50$ 且只包含大小写字母)

输出格式

输出解密后的字符串。

输入输出样例 #1

输入 #1

1
GSOOWFASOq

输出 #1

1
Trvdizrrvj

题目分析

解题思路

  1. 题目要求解密一个按特定规则加密的字符串。

  2. 解密规则分析:
    • 字母表循环左移三位的逆操作(右移三位)
    • 字符串逆序存储的逆操作(再次逆序)
    • 大小写反转的逆操作(再次反转)
  3. 具体思路:
    • 输入加密后的字符串
    • 按照加密的逆序进行解密:
      • 先将字符串中的大小写字母反转
      • 将字符串整体逆序
      • 对每个字符进行字母表右移三位操作
    • 输出解密后的结果
  4. 时间复杂度分析:
    • 大小写反转需要遍历一次,O(n)
    • 字符串逆序需要遍历一次,O(n)
    • 字母表移位需要遍历一次,O(n)
    • 总体时间复杂度为O(n),其中n为字符串长度
    • 空间复杂度为O(1),仅需要常数额外空间


示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <cctype>
#include <iostream>
#include <string>
#include <algorithm>

int main() {
    // 声明字符串变量用于存储输入
    std::string input;
    // 从标准输入读取加密字符串
    std::cin >> input;
    
    // 第一步:大小写反转
    for (int i = 0; i < input.length(); i++) {
        if (std::islower(input[i])) {
            input[i] = std::toupper(input[i]);
        } else if (std::isupper(input[i])) {
            input[i] = std::tolower(input[i]);
        }
    }
    
    // 第二步:字符串逆序
    std::reverse(input.begin(), input.end());
    
    // 第三步:字母表循环左移三位解密
    for (int i = 0; i < input.length(); i++) {
        if (input[i] == 'x') {
            input[i] = 'a';
        } else if (input[i] == 'y') {
            input[i] = 'b';
        } else if (input[i] == 'z') {
            input[i] = 'c';
        } else if (input[i] == 'X') {
            input[i] = 'A';
        } else if (input[i] == 'Y') {
            input[i] = 'B';
        } else if (input[i] == 'Z') {
            input[i] = 'C';
        } else {
            // 其他字母向后移动3位
            input[i] = input[i] + 3;
        }
    }
    
    // 输出解密后的结果
    std::cout << input;
    return 0;
}

所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code

GESP各级别考纲要点、知识拓展和练习题目清单详见C++学习项目主页

luogu-”系列题目已加入洛谷Java、C++初学团队作业清单,可在线评测,团队名额有限,欢迎加入。

bcqm-”系列题目可在编程启蒙题库进行在线评测。

本文由作者按照 CC BY 4.0 进行授权