把每个小写字母转成 0 到 25 的编号,平移 n 位后取模再转回字符。
OJ: luogu
题目 ID: P1914
难度:入门
标签:字符串模拟python
日期: 2026-07-15 20:30
题意
给定一个位移量 n 和一个只含小写字母的字符串。每个字母向后移动 n 位,超过 z 后从 a 继续循环,输出移动后的密码。
思路
把字符看成字母表中的编号:
text
a -> 0, b -> 1, ..., z -> 25一个字符 ch 平移 n 位后,新编号是:
text
(old + n) % 26再把新编号加回到 'a' 的 ASCII 编码,就能得到新字符。
这题是字符编码和取模循环练习,不创建 brute.py。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:用input()读取字符串,用列表收集结果后"".join(...)输出。/home/rainboy/mycode/hugo-blog/content/program_language/python/oj_input_output_cheatsheet.md:第一行整数、第二行字符串可以分别读取。ord(ch)把字符转成编码,chr(x)把编码转回字符。% 26表达字母表循环。
代码
python
n = int(input())
s = input().strip()
answer = []
for ch in s:
offset = (ord(ch) - ord("a") + n) % 26
answer.append(chr(ord("a") + offset))
print("".join(answer))cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
char s[55]; // 原始密码字符串
int n; // 位移量
int main() {
cin >> n >> s;
int len = strlen(s);
for (int i = 0; i < len; i++) {
// 字母编号 0~25,平移 n 位后取模
int idx = (s[i] - 'a' + n) % 26;
s[i] = 'a' + idx;
}
cout << s;
return 0;
}Pythonic 写法
用 str.maketrans / translate 做凯撒位移:
python
n = int(input())
s = input().strip()
table = str.maketrans(
{chr(ord("a") + i): chr(ord("a") + (i + n) % 26) for i in range(26)}
)
print(s.translate(table))复杂度
设字符串长度为 m,时间复杂度是
总结
凯撒密码的关键是先把字母映射成数字,再用取模处理循环。