5 条题解
-
14
#include<bits/stdc++.h> using namespace std; string k,C; char M[130][130]; // 在M[i][i]中,含义为密文i通过密钥j对应的明文 int main(){ ios::sync_with_stdio(false); // 输入输出加速 cin.tie(0); cout.tie(0); cin>>k>>C; // a=97 A=65 Z=90 z=122 这是几个重要英文的ascll值 for(int i=int('A');i<=int('Z');i++){ // i这里是明文 for(int j=int('A');j<=int('Z');j++){ // j这里是密钥 int num=i-int('A')+j; // 由题目中的图片找规律计算对应的密文 while(num>90)num-=26; // 密文的ascll大于Z的话就要回到A M[num][j]=M[num][j+32]=char(i); // 存储密文密钥对应的明文 // 因为忽略转换过程大小写,所以密钥对应的大写值也要存储 } } for(int i=int('a');i<=int('z');i++){ for(int j=int('a');j<=int('z');j++){ int num=i-int('a')+j; while(num>122)num-=26; // 大于z要回到a M[num][j]=M[num][j-32]=char(i); // 因为忽略转换过程大小写,所以密钥对应的小写值也要存储 } } int cnt=0,lenC=C.size(),lenK=k.size(); for(int i=0;i<lenC;i++){ // 遍历字符串C cout<<M[int(C[i])][int(k[cnt++])]; // 输出密文Ci与密钥ki对应的明文Mi if(cnt==lenK)cnt=0; // 密钥长度小于密文长度时重新遍历密钥 } return 0; }
-
4
这一题无非是绕来绕去搞得十分复杂,但思路理清晰后还是比较简单的。
第一种利用设置二维列表。方法复杂度很小,但是你打出这个数组的时间就慢的不得了,这个数组如下
int jm[45][45]= {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0}, {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1}, {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2}, {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3}, {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4}, {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5}, {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6}, {8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7}, {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8}, {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9}, {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10}, {12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11}, {13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12}, {14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13}, {15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}, {18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, {19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}, {20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}, {21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, {22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}, {23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22}, {24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}, {25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}};
打完这一个数组,在考试的时候已经花了将近七八分钟。所以在考试时这是没有办法的办法。
但是主函数里的东西明显的就少,注意一下,最好不要经常用万能头文件,这是一个偷懒且不好的习惯,这里需要以下头文件:
#include <cstring> #include <cstdio>
还需要用到头结点:
#define N 1005 #define rep(a,b,c) for(int a=b;a<=c;++a)
头结点作用:便于首元结点的处理,最后结点的指针域为空。
以下是主函数:
int main() { scanf("%s",k); scanf("%s",s); int lk=strlen(k),ls=strlen(s),j=0; rep(i,0,ls-1) { int p=k[j]-'A',g=s[i]-'A',f=0; if(p>25) p-=32; if(g>25) g-=32,f=1; rep(k,0,25) if(jm[p][k]==g) f?putchar(k+'A'+32):putchar(k+'A'); j=(j+1)%lk; } return 0; }
这一串主函数很好理解,不多加赘述。
总体呈现:
#include <cstring> #include <cstdio> #define N 1005 #define rep(a,b,c) for(int a=b;a<=c;++a) int jm[45][45]= {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0}, {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1}, {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2}, {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3}, {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4}, {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5}, {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6}, {8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7}, {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8}, {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9}, {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10}, {12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11}, {13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12}, {14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13}, {15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}, {18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, {19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}, {20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}, {21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, {22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}, {23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22}, {24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}, {25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}}; char k[N],s[N]; int main() { scanf("%s",k); scanf("%s",s); int lk=strlen(k),ls=strlen(s),j=0; rep(i,0,ls-1) { int p=k[j]-'A',g=s[i]-'A',f=0; if(p>25) p-=32; if(g>25) g-=32,f=1; rep(k,0,25) if(jm[p][k]==g) f?putchar(k+'A'+32):putchar(k+'A'); j=(j+1)%lk; } return 0; }
第二种方法是大家都比较喜欢的方法:遍历密钥与密文,但是注意密钥、密文的大小写。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main() { char key[1000],secret[1000]; int len1,len2; int i,j; gets(key);//输入密钥 gets(secret);//输入密文 len1=strlen(key);//求密钥长度 len2=strlen(secret);//求密文长度 for(i=0; i<len1; i++) //将密钥转换为大写字母 if((key[i]>='a')&&(key[i]<='z')) key[i]-=32; for(i=0,j=0; i<len2; i++) //从头开始解密 { if(secret[i]<='Z')//大写的情况 { secret[i]=secret[i]-(key[j]-'A');//按规则解密 j++; if(secret[i]<'A')//若明文小于A secret[i]='Z'-('A'-secret[i])+1;//从字母表倒序转换 } else//小写的情况 { secret[i]=secret[i]-(key[j]-'A');//按规则解密 j++; if(secret[i]<'a')//若明文小于a secret[i]='z'-('a'-secret[i])+1;//从字母表倒序转换 } if(j>len1-1)//若明文长度大于密钥长度,重复使用密钥 j=0; } cout<<secret<<endl; return 0; }
这就是两种写法。
AC Code1
#include <cstring> #include <cstdio> #define N 1005 #define rep(a,b,c) for(int a=b;a<=c;++a) int jm[45][45]= {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0}, {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1}, {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2}, {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3}, {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4}, {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5}, {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6}, {8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7}, {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8}, {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9}, {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10}, {12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11}, {13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12}, {14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13}, {15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}, {18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, {19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}, {20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}, {21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, {22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}, {23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22}, {24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}, {25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}}; char k[N],s[N]; int main() { scanf("%s",k); scanf("%s",s); int lk=strlen(k),ls=strlen(s),j=0; rep(i,0,ls-1) { int p=k[j]-'A',g=s[i]-'A',f=0; if(p>25) p-=32; if(g>25) g-=32,f=1; rep(k,0,25) if(jm[p][k]==g) f?putchar(k+'A'+32):putchar(k+'A'); j=(j+1)%lk; } return 0; }
AC Code 2
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main() { char key[1000],secret[1000]; int len1,len2; int i,j; gets(key);//输入密钥 gets(secret);//输入密文 len1=strlen(key);//求密钥长度 len2=strlen(secret);//求密文长度 for(i=0; i<len1; i++) //将密钥转换为大写字母 if((key[i]>='a')&&(key[i]<='z')) key[i]-=32; for(i=0,j=0; i<len2; i++) //从头开始解密 { if(secret[i]<='Z')//大写的情况 { secret[i]=secret[i]-(key[j]-'A');//按规则解密 j++; if(secret[i]<'A')//若明文小于A secret[i]='Z'-('A'-secret[i])+1;//从字母表倒序转换 } else//小写的情况 { secret[i]=secret[i]-(key[j]-'A');//按规则解密 j++; if(secret[i]<'a')//若明文小于a secret[i]='z'-('a'-secret[i])+1;//从字母表倒序转换 } if(j>len1-1)//若明文长度大于密钥长度,重复使用密钥 j=0; } cout<<secret<<endl; return 0; }
-
2
首先,我们需要定义一个函数,用于执行Vigenère密码的加密解密操作。然后,我们读取输入数据,并调用这个函数来计算明文。最后,我们将结果输出。
#include <iostream> #include <string> #include <map> #include <algorithm> using namespace std; // 定义一个map,用于存储密钥和对应的字典序 map<char, int> key_order; // 初始化密钥和字典序的映射关系 void init_key_order() { for (char c = 'a'; c <= 'z'; ++c) { key_order[c] = c - 'a'; } for (char c = 'A'; c <= 'Z'; ++c) { key_order[c] = c - 'A' + 26; } } // 执行Vigenère密码的加密解密操作 string vigenère_cipher(const string &m, const string &k) { string result; int key_len = k.size(); int plain_len = m.size(); // 初始化密钥和明文的映射关系 map<int, char> plain_order; for (int i = 0; i < plain_len; ++i) { char c = m[i]; int j; if (key_order.find(c) != key_order.end()) { j = key_order[c] + key_len * i; } else { j = key_order[tolower(c)] + key_len * i; } plain_order[j] = c; } // 将密文转换为明文 for (int i = 0; i < key_len; ++i) { int j = key_order[k[i]]; if (plain_order.find(j) != plain_order.end()) { result.push_back(plain_order[j]); } } return result; } int main() { init_key_order(); string key, cipher; cin >> key >> cipher; string plain = vigenère_cipher(cipher, key); cout << plain << endl; return 0; }
这段代码首先定义了一个map,用于存储密钥和对应的字典序。然后定义了一个函数
vigenère_cipher
,用于执行Vigenère密码的加密解密操作。这个函数首先初始化密钥和明文的映射关系,然后将密文转换为明文。最后,我们读取输入数据,并调用vigenère_cipher
函数来计算明文。 -
0
1 #include<iostream> #include<cstdio> #include<cstring> using namespace std;
int main() { char key[1000],secret[1000]; int len1,len2; int i,j;
gets(key);//输入密钥 gets(secret);//输入密文 len1=strlen(key);//求密钥长度 len2=strlen(secret);//求密文长度 for(i=0; i<len1; i++) //将密钥转换为大写字母 if((key[i]>='a')&&(key[i]<='z')) key[i]-=32; for(i=0,j=0; i<len2; i++) //从头开始解密 { if(secret[i]<='Z')//大写的情况 { secret[i]=secret[i]-(key[j]-'A');//按规则解密 j++; if(secret[i]<'A')//若明文小于A secret[i]='Z'-('A'-secret[i])+1;//从字母表倒序转换 } else//小写的情况 { secret[i]=secret[i]-(key[j]-'A');//按规则解密 j++; if(secret[i]<'a')//若明文小于a secret[i]='z'-('a'-secret[i])+1;//从字母表倒序转换 } if(j>len1-1)//若明文长度大于密钥长度,重复使用密钥 j=0; } cout<<secret<<endl; return 0;
} 2 #include<bits/stdc++.h> using namespace std; string k,C; char M[130][130]; // 在M[i][i]中,含义为密文i通过密钥j对应的明文 int main(){ ios::sync_with_stdio(false); // 输入输出加速 cin.tie(0); cout.tie(0); cin>>k>>C; // a=97 A=65 Z=90 z=122 这是几个重要英文的ascll值 for(int i=int('A');i<=int('Z');i++){ // i这里是明文 for(int j=int('A');j<=int('Z');j++){ // j这里是密钥 int num=i-int('A')+j; // 由题目中的图片找规律计算对应的密文 while(num>90)num-=26; // 密文的ascll大于Z的话就要回到A M[num][j]=M[num][j+32]=char(i); // 存储密文密钥对应的明文 // 因为忽略转换过程大小写,所以密钥对应的大写值也要存储 } } for(int i=int('a');i<=int('z');i++){ for(int j=int('a');j<=int('z');j++){ int num=i-int('a')+j; while(num>122)num-=26; // 大于z要回到a M[num][j]=M[num][j-32]=char(i); // 因为忽略转换过程大小写,所以密钥对应的小写值也要存储 } } int cnt=0,lenC=C.size(),lenK=k.size(); for(int i=0;i<lenC;i++){ // 遍历字符串C cout<<M[int(C[i])][int(k[cnt++])]; // 输出密文Ci与密钥ki对应的明文Mi if(cnt==lenK)cnt=0; // 密钥长度小于密文长度时重新遍历密钥 } return 0; } 3 #include <cstring> #include <cstdio> #define N 1005 #define rep(a,b,c) for(int a=b;a<=c;++a)
int jm[45][45]= {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0}, {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1}, {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2}, {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3}, {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4}, {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5}, {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6}, {8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7}, {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8}, {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9}, {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10}, {12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11}, {13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12}, {14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13}, {15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}, {18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, {19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}, {20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}, {21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, {22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}, {23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22}, {24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}, {25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}}; char k[N],s[N]; int main() { scanf("%s",k); scanf("%s",s); int lk=strlen(k),ls=strlen(s),j=0; rep(i,0,ls-1) { int p=k[j]-'A',g=s[i]-'A',f=0; if(p>25) p-=32; if(g>25) g-=32,f=1; rep(k,0,25) if(jm[p][k]==g) f?putchar(k+'A'+32):putchar(k+'A'); j=(j+1)%lk; } return 0; } 4 #include <iostream> #include <string> #include <map> #include <algorithm>
using namespace std;
// 定义一个map,用于存储密钥和对应的字典序 map<char, int> key_order;
// 初始化密钥和字典序的映射关系 void init_key_order() { for (char c = 'a'; c <= 'z'; ++c) { key_order[c] = c - 'a'; } for (char c = 'A'; c <= 'Z'; ++c) { key_order[c] = c - 'A' + 26; } }
// 执行Vigenère密码的加密解密操作 string vigenère_cipher(const string &m, const string &k) { string result; int key_len = k.size(); int plain_len = m.size();
// 初始化密钥和明文的映射关系 map<int, char> plain_order; for (int i = 0; i < plain_len; ++i) { char c = m[i]; int j; if (key_order.find(c) != key_order.end()) { j = key_order[c] + key_len * i; } else { j = key_order[tolower(c)] + key_len * i; } plain_order[j] = c; } // 将密文转换为明文 for (int i = 0; i < key_len; ++i) { int j = key_order[k[i]]; if (plain_order.find(j) != plain_order.end()) { result.push_back(plain_order[j]); } } return result;
}
int main() { init_key_order(); string key, cipher; cin >> key >> cipher; string plain = vigenère_cipher(cipher, key); cout << plain << endl; return 0; }
- 1
信息
- ID
- 2057
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 3
- 标签
- (无)
- 递交数
- 267
- 已通过
- 135
- 上传者