按加密逆序撤销三步变换:大小写反转、逆序、字母表循环右移 3,线性还原原文。
OJ: roj
题目 ID: 1137
难度:入门
标签:字符串模拟python
创建: 2026-09-29 20:26
更新: 2026-10-05 03:07
题目描述
给定一个长度小于
- 每个字母在字母表中循环左移 3 位;
- 字符串整体逆序;
- 大小写反转。
输出解密后的原文。
样例:输入 GSOOWFASOq,输出 Trvdizrrvj。
思路
加密顺序是“左移 3 → 逆序 → 大小写反转”,解密按相反顺序撤销。大小写反转和逆序都是自逆变换;左移 3 的逆是循环右移 3。对字符串先大小写反转,再逆序,最后每个字母右移 3 位即可。
参考代码
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-07-06 10:00
# update_at: 2026-07-06 10:00
import sys
import string
SHIFT = 3 # 加密时字母表循环左移的位数,解密时右移回来
# 解密用的字母表右移 3 翻译表:'a'->'d'、'z'->'c',大小写各一套
_LOWER = string.ascii_lowercase
SHIFTED = _LOWER[SHIFT:] + _LOWER[:SHIFT]
TABLE = str.maketrans(string.ascii_letters, SHIFTED + SHIFTED.upper())
def solve() -> None:
cipher = sys.stdin.read().strip() # 密文,长度 < 50,只含大小写字母
# 加密顺序:左移 3 → 逆序 → 大小写反转;解密按逆序撤销
swapped = cipher.swapcase() # 撤销第 3 步:大小写反转(自逆)
reversed_ = swapped[::-1] # 撤销第 2 步:逆序(自逆)
print(reversed_.translate(TABLE)) # 撤销第 1 步:循环右移 3
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 <iostream>
#include <algorithm>
#include <string>
using namespace std;
typedef long long ll;
string s; // 密文字符串,长度小于 50,只含大小写字母
// 把字符 c 在大小写字母环上循环右移 3 位
char shift_right(char c) {
if (c >= 'a' && c <= 'z') return (c - 'a' + 3) % 26 + 'a';
if (c >= 'A' && c <= 'Z') return (c - 'A' + 3) % 26 + 'A';
return c;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> s;
// 解密按加密逆序撤销:先大小写反转,再逆序,最后循环右移 3
for (ll i = 0; i < (ll)s.size(); i++) {
if (s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 'a' + 'A';
else s[i] = s[i] - 'A' + 'a';
}
reverse(s.begin(), s.end()); // 逆序撤销
for (ll i = 0; i < (ll)s.size(); i++) s[i] = shift_right(s[i]); // 右移 3
cout << s << '\n';
return 0;
}