【GESP】C++三级练习 luogu-B2116 加密的病历单
GESP三级练习,字符串练习(C++三级大纲中6号知识点,字符串),难度★★☆☆☆。
luogu-B2116 加密的病历单
题目要求
题目描述
小英是药学专业大三的学生,暑假期间获得了去医院药房实习的机会。
在药房实习期间,小英扎实的专业基础获得了医生的一致好评,得知小英在计算概论中取得过好成绩后,主任又额外交给她一项任务,解密抗战时期被加密过的一些伤员的名单。
经过研究,小英发现了如下加密规律(括号中是一个“原文 → 密文”的例子)
原文中所有的字符都在字母表中被循环左移了三个位置($\text{bcd} \to \text{yza}$)
逆序存储($\text{abcd} \to \text{dcba}$)
大小写反转($\text{abXY} \to \text{ABxy}$)
现在给出一个加密的字符串,请你将其解密。
输入格式
一个加密的字符串。(长度小于 $50$ 且只包含大小写字母)
输出格式
输出解密后的字符串。
输入输出样例 #1
输入 #1
1
GSOOWFASOq
输出 #1
1
Trvdizrrvj
题目分析
解题思路
题目要求解密一个按特定规则加密的字符串。
- 解密规则分析:
- 字母表循环左移三位的逆操作(右移三位)
- 字符串逆序存储的逆操作(再次逆序)
- 大小写反转的逆操作(再次反转)
- 具体思路:
- 输入加密后的字符串
- 按照加密的逆序进行解密:
- 先将字符串中的大小写字母反转
- 将字符串整体逆序
- 对每个字符进行字母表右移三位操作
- 输出解密后的结果
- 时间复杂度分析:
- 大小写反转需要遍历一次,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 进行授权