同时维护密文到明文和明文到密文映射,验证完整双射后翻译电报。
OJ: noi_openjudge
题目 ID: ch0107-11
难度:普及-
标签:字符串映射模拟python
日期: 2026-07-30 23:01
题意
已知一条密文及其原文,恢复代换密码并翻译新密文;映射必须是一一对应且覆盖全部
思路
cipher_to_plain 记录密字对应的原字,plain_to_cipher 记录反向关系。扫描已知对应时,两张表都不能和已有记录冲突。最后检查密文字母是否恰有
代码
Python代码
python
ciphertext = input().strip()
plaintext = input().strip()
message = input().strip()
cipher_to_plain = {}
plain_to_cipher = {}
is_valid = True
for cipher, plain in zip(ciphertext, plaintext):
if cipher_to_plain.get(cipher, plain) != plain or plain_to_cipher.get(plain, cipher) != cipher:
is_valid = False
break
cipher_to_plain[cipher] = plain
plain_to_cipher[plain] = cipher
if not is_valid or len(cipher_to_plain) != 26:
print("Failed")
else:
print("".join(cipher_to_plain[character] for character in message))C++代码
cpp
/*
* AC
* BB
*
* */
#include <cstdio>
#include <cstring>
char str1[500];
char str2[500];
char str3[500];
int _map[500] = {0};
int _map2[500] = {0};
int main(){
scanf("%s",str1+1);
scanf("%s",str2+1);
scanf("%s",str3+1);
int len = strlen(str1+1);
int i,j;
for (i=1;i<=len;i++){
char c = str1[i];
char d = str2[i];
if(_map[c] == 0 && _map2[d] == 0 ){
_map[c] = d;
_map2[d] = c;
}
else if(_map[c] != 0 && _map[c] != d){
printf("Failed");
return 0;
}
else if( _map2[d] != 0 && _map2[d] != c){
printf("Failed");
return 0;
}
}
for (i='A';i<='Z';i++){
if( _map[i] == 0){
printf("Failed");
return 0;
}
}
len = strlen(str3+1);
for (i=1;i<=len;i++){
printf("%c",_map[ str3[i]]);
}
return 0;
}复杂度
设三行字符串总长度为
总结
一一映射校验应同时检查正向和反向,才能发现两个原字共用一个密字。