OneCoder Avatar
OneCodercoderli.com · 937 篇博文
三级

C++ 算法考级专栏

真题分析、矩阵探测、递归回溯与基础语法

🎨 视觉封面

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

📅 2025-04-02·✍️ OneCoder·计算中...·⏱️ 6 分钟
#GESP#C++#字符串

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

luogu-B2116 加密的病历单

题目要求

题目描述

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

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

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

  1. 原文中所有的字符都在字母表中被循环左移了三个位置(bcdyza\text{bcd} \to \text{yza}
  2. 逆序存储(abcddcba\text{abcd} \to \text{dcba}
  3. 大小写反转(abXYABxy\text{abXY} \to \text{ABxy}

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

输入格式

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

输出格式

输出解密后的字符串。

输入输出样例 #1

输入 #1

BASH
GSOOWFASOq

输出 #1

BASH
Trvdizrrvj

题目分析

解题思路

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

  2. 解密规则分析:

    • 字母表循环左移三位的逆操作(右移三位)
    • 字符串逆序存储的逆操作(再次逆序)
    • 大小写反转的逆操作(再次反转)
  3. 具体思路:

    • 输入加密后的字符串
    • 按照加密的逆序进行解密:
      • 先将字符串中的大小写字母反转
      • 将字符串整体逆序
      • 对每个字符进行字母表右移三位操作
    • 输出解密后的结果
  4. 时间复杂度分析:

    • 大小写反转需要遍历一次,O(n)O(n)
    • 字符串逆序需要遍历一次,O(n)O(n)
    • 字母表移位需要遍历一次,O(n)O(n)
    • 总体时间复杂度为O(n)O(n),其中nn为字符串长度
    • 空间复杂度为O(1)O(1),仅需要常数额外空间

示例代码

CPP
#include <cctype>    // 包含字符处理相关函数,如islower、isupper等
#include <iostream>  // 包含输入输出流
#include <string>    // 包含字符串类
#include <algorithm> // 包含算法库,使用reverse函数

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]);
        }
    }

    // 第二步:字符串逆序
    // 使用algorithm库中的reverse函数将字符串整体反转
    std::reverse(input.begin(), input.end());

    // 第三步:字母表循环左移三位解密
    // 遍历字符串中的每个字符
    for (int i = 0; i < input.length(); i++) {
        // 处理特殊情况:x、y、z需要循环到a、b、c
        if (input[i] == 'x') {
            input[i] = 'a';
        } else if (input[i] == 'y') {
            input[i] = 'b';
        } else if (input[i] == 'z') {
            input[i] = 'c';
        }
        // 处理特殊情况:X、Y、Z需要循环到A、B、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位
            // ASCII码值加3实现字母表右移三位
            input[i] = input[i] + 3;
        }
    }

    // 输出解密后的结果
    std::cout << input;
    return 0;
}

💡 OneCoder 资源指引

所有代码开源上传至 GitHub:yummy-code 仓库 · GESP 专题站:GESP WIKI

🤝 技术交流与答疑

欢迎加入:C++ GESP/CSP 考级答疑群(688906745)Java/Python交流群(982860385),点击可直接加群。

📚

猜你想读 · 相关文章推荐

OneCoder

OneCoder (lihongzheshuai)

一个中年人的自留地,记录学习 C++、GESP/NOI、Java、Python 与算法架构的心得体会。本站唯一网址:coderli.com

💬 读者留言与交流

0 条讨论
✨ 支持 Markdown 语法格式
还没有留言,快来成为第一个讨论者吧!