题目
Description
有一种密码的工作原理是:
首先选择一个单词作为密钥, 如TRAILBLAZERS,如果单词中有重复字母,则只保留第1个,其余几个丢弃。现在修改过的那个单词列于字母表下面,如下
所示:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
T R A I L B Z E S
然后,用字母表中没出现的字母将密钥填充完整,得到:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
T R A I L B Z E S C D F G H J K M N O P Q U V W X Y
对信息加密时,将原文中的所有字母,按以上对应关系一一用密钥字母取代,因此使用这个密钥就可以对原文信息 进行加密。同样,也可以使用这个密钥进行解密。Input
输入有多组,每组数据的第一行为一个整数0、1、2, 1表示加密;2表示解密;0
表示结束,并且不需要处理。若第一行为1或2, 则第二行为密钥单词,第三行为
进行加密 或解密的原文或密文。其中密钥单词长度不超过15个字符,原文长度在
200个字符以内。Output
根据加密或解密的要求和密钥,输出加密 或解密的密文或原文。
Sample Input
1
TRAILBLAZERS
ATTACK AT DAWN
2
TRAILBLAZERS
TPPTAD TP ITVH
0Sample Output
TPPTAD TP ITVH
ATTACK AT DAWN
题解
首先建立好原文和密文字符的映射
而后使用 getchar
一个一个读入字符
数据的任意地方可能会有任意数量的空格
- 如果是空格
直接输出 - 如果是换行(数据结束)
返回 - 如果是字母
根据映射输出
代码
/* By:OhYee Github:OhYee Blog:http://www.oyohyee.com/ Email:oyohyee@oyohyee.com かしこいかわいい? エリーチカ! 要写出来Хорошо的代码哦~ */ #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> #include <functional> using namespace std; const int maxn = 20; const int maxm = 205; char key[maxn]; char word[maxm]; char KtoA[26]; char AtoK[26]; void GetMap() { memset(KtoA,0,sizeof(KtoA)); memset(AtoK,0,sizeof(AtoK)); int pos = 0; int len = strlen(key); for(int i = 0;i < len;i++) { if(KtoA[key[i] - 'A'] == 0) { KtoA[key[i] - 'A'] = pos + 'A'; AtoK[pos] = key[i]; pos++; } } for(int i=0;i < 26;i++) { if(KtoA[i] == 0) { KtoA[i] = pos + 'A'; AtoK[pos++] = i + 'A'; } } } bool Do() { int com; scanf("%d",&com); if(com == 0) return false; scanf("\n%s",key); GetMap(); char c; int i = 0; while(!(((c = getchar()) >= 'A'&&c <= 'Z') || (c >= 'a'&&c <= 'z'))); while((c >= 'A'&&c <= 'Z') || (c >= 'a'&&c <= 'z')||c==' ') { if(c == ' ') { putchar(' '); }else { if(com == 1) { putchar(AtoK[c-'A']); } else { putchar(KtoA[c - 'A']); } } c = getchar(); } putchar('\n'); return true; } int main() { while(Do()); return 0; }