对大写密文字母在 26 个位置上循环左移五位,保留非字母字符。
OJ: noi_openjudge
题目 ID: ch0107-10
难度:入门
标签:字符串模拟python
创建: 2026-07-30 23:01
更新: 2026-07-31 11:59
后置题目
roj 3598[NOIP2012-提高] Vigenère 密码B 把 A 教的“字母转下标后减去偏移、%26 再转回字符”直接用作逐位解密,只是把固定偏移 5 换成密钥字母并叠加 i%len(key) 循环。roj 1402Vigenère密码B 的 Vigenère 解法正是把 A 教的「字母转下标后减位移再 % 26 回绕转回字符」这一凯撒移位步骤逐位套用,只把固定位移 5 换成密钥位 k_{i mod n} 并补上密钥循环与大小写跟随noi_openjudge ch0112-08Vigenère密码B 的逐字母解密复用 A 的「字母转 0-25 下标、减位移、模 26 回绕、转回字符」这一步,只是把固定位移 5 换成按 key[i%len] 变化的位移,再叠加 A 未教的大小写 ASCII 基准选择与循环密钥取模。
题意
凯撒密文将明文大写字母后移五位。给定密文,恢复明文;非字母字符不变。
思路
把大写字母映射到 % 26 处理 A 前面的循环,再转回字符。非大写字母原样返回。
代码
Python代码
python
def decrypt(character: str) -> str:
if "A" <= character <= "Z":
return chr((ord(character) - ord("A") - 5) % 26 + ord("A"))
return character
print("".join(decrypt(character) for character in input()))C++代码
cpp
#include <cstdio>
#include <cstring>
#define maxn 500
int n;
char str[maxn];
int idx=1;
char mi[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char ming[] = "VWXYZABCDEFGHIJKLMNOPQRSTU";
int main(){
char t;
int i;
while(1){
scanf("%c",&t);
if( t == '\n' || t == '\r' || t == EOF)
break;
str[idx] = t;
idx++;
}
idx--;
for(i=1;i<=idx;i++){
char c = str[i];
if( c >= 'A' && c <= 'Z'){
printf("%c",ming[ c-'A']);
}
else
printf("%c",c);
}
return 0;
}复杂度
时间复杂度和输出空间均为
总结
循环字母表的平移可统一为“转下标、取模、转回字符”。