题解:洛谷 P1914 小书童——凯撒密码

【题目来源】

洛谷:P1914 小书童——凯撒密码 - 洛谷

【题目描述】

蒟蒻虽然忘记密码,但他还记得密码是由一个字符串组成。密码是由原文字符串(由不超过 \(50\) 个小写字母组成)中每个字母向后移动 \(n\) 位形成的。z 的下一个字母是 a,如此循环。他现在找到了移动前的原文字符串及 \(n\),请你求出密码。

【输入】

第一行:\(n\)。第二行:未移动前的一串字母。

【输出】

一行,是此蒟蒻的密码。

【输入样例】

1
qwe

【输出样例】

rxf

【核心思想】

  1. 问题分析:给定一个由小写字母组成的字符串(长度不超过 50)和一个整数 \(n\),需要将每个字母向后移动 \(n\) 位,形成凯撒密码。当移动超过 'z' 时,从 'a' 重新开始(循环移位)。本质是字符串的循环移位问题,利用模运算处理边界。

  2. 算法选择

    • 遍历 + 模运算:对每个字符,将其转换为 0~25 的数字('a' 对应 0),加上 \(n\) 后对 26 取模,再转换回字符。这是最通用且安全的方法。
    • 边界判断(备选):也可以像代码中那样,先尝试直接加 \(n\),若超过 'z' 则用模运算修正。但使用统一模运算更简洁。
  3. 关键步骤

    • 读入:读取 \(n\) 和字符串 \(s\)
    • 遍历并转换:对于每个字符 \(s[i]\)
      • 计算偏移后的字符:s[i] = (s[i] - 'a' + n) % 26 + 'a'
    • 输出:输出转换后的字符串。
  4. 时间/空间复杂度

    • 时间复杂度:\(O(L)\),其中 \(L\) 是字符串长度。
    • 空间复杂度:\(O(1)\),在原字符串上直接修改。
  5. 字符串与模运算

    • 模运算处理循环:将字母映射到 0~25 的整数,加 \(n\) 后对 26 取模,可以自然处理 'z''a' 的循环。
    • \(n\) 的范围:题目未明确 \(n\) 的范围,但模运算可以处理任意整数 \(n\)(包括负数,但本题 \(n\) 为正整数)。
    • 适用场景:凯撒密码是古典密码学中最简单的加密方式,也是字符串处理入门常见题。

【算法标签】

入门 #字符串入门

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件(万能头文件)
using namespace std;      // 使用标准命名空间

int main()
{
    int n;               // 定义变量:字母位移量
    string s;            // 定义字符串:存储待加密的字符串

    cin >> n >> s;       // 输入位移量和字符串

    // 遍历字符串中的每个字符
    for (int i = 0; i < s.length(); i++)
    {
        // 判断字符位移后是否仍在字母z范围内
        if (s[i] + n <= 'z')
        {
            // 直接进行位移
            s[i] += n;
        }
        else
        {
            // 处理越界情况,使用模运算实现循环位移
            // (n-26)%26 确保位移量在合理范围内
            s[i] = s[i] + (n - 26) % 26;
        }
    }

    cout << s;           // 输出加密后的字符串

    return 0;            // 程序正常结束
}

【运行结果】

1
qwe
rxf
posted @ 2026-08-30 09:21  团爸讲算法  阅读(29)  评论(0)    收藏  举报