逐字符模拟加密规则:字母在大小写各自的 26 环上右移一位,z/Z 绕回,非字母原样保留。
OJ: roj
题目 ID: 1136
难度:入门
标签:入门字符串模拟表驱动python
创建: 2026-09-29 20:26
更新: 2026-10-05 03:07
题目描述
对给定的一个字符串加密:把其中 a-y、A-Y 的字母用其后继字母替代,把 z 和 Z 用 a 和 A 替代,其他非字母字符不变。输入一行,包含一个字符串,长度小于 80 个字符;输出加密后的字符串。
样例输入 Hello! How are you!,样例输出 Ifmmp! Ipx bsf zpv!。
思路
逐字符扫描:小写和大写字母各自构成一个长度为 26 的循环,右移一位即可,z/Z 单独绕回 a/A;非字母字符原样保留。注意必须整行读入,空格和标点才不会被丢掉。
参考代码
Python 版:
python
#!/usr/bin/env python3
# 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-09-29 20:26
# update_at: 2026-09-29 20:26
import sys
# 环移规则表:26 个小写 + 26 个大写字母各自映到字母表上的后继,
# z→a、Z→A 由同一张表覆盖;未列出的字符(空格、标点、换行)查表失败即原样保留。
SUCCESSOR = str.maketrans(
"abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ", # 源:26 小写 + 26 大写
"bcdefghijklmnopqrstuvwxyza" "BCDEFGHIJKLMNOPQRSTUVWXYZA", # 目标:各右移一位(尾回环)
)
def solve() -> None:
text = sys.stdin.buffer.read().decode()
# 换行不属于要加密的内容:先摘掉行尾换行,再由 print 补回恰好一个。
print(text.translate(SUCCESSOR).rstrip("\n"))
if __name__ == "__main__":
solve()C++ 版(同一算法):
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-10-05 03:07
* update_at: 2026-10-05 03:07
*/
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
typedef long long ll;
string s; // 待加密的整行字符串(长度小于 80)
// 对单个字符加密:字母在各自 26 环上右移一位,z/Z 绕回,其他字符不变
char encode(char c) {
if (c >= 'a' && c <= 'z') return (c - 'a' + 1) % 26 + 'a';
if (c >= 'A' && c <= 'Z') return (c - 'A' + 1) % 26 + 'A';
return c;
}
int main() {
// 用 getline 整行读入,保证空格、标点原样保留
getline(cin, s);
ll len = s.size(); // 长度小于 80,用 ll 存下标足够
for (ll i = 0; i < len; i++) s[i] = encode(s[i]);
cout << s << "\n";
return 0;
}