【问题描述】
有一位法国外交家发明了一种神奇的算法明文是M,密钥是k,密文是C。加密规则如下:
c[i]=m[i]@k[i]
加密注意点;
1、加密时忽略明文和密钥的大小写,并在密文中保持明文的大小写
2、当明文M的长度大于密钥K的长度时,K可以被循环使用。
例如,明文 M=HelloworldM=Helloworld ,密钥 k=abck=abc 时,密文 C=HfnlpyosndC=Hfnlpyosnd 。
【输入输出格式】
共两行,第一行为密钥K,长度不超过100;第二行为密文M,长度不超过1000.
【输出样例】
CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm
【输出样例】
Wherethereisawillthereisaway
【分析】
利用密文还原明文
先把密钥转换可以加减的[0,25]的数字,如下依次操作每个密文:
把密文也转化成[0,25]的数字,并用变量tmp保留其大小写。
把密文减密钥,如果结果小于0,则再加上26
最后再加上tmp转换为明文
如下附上代码一份:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1010;
char m[maxn],k[maxn];
int lm,lk,key[maxn];
int main()
{
freopen("vigenere.in","r",stdin);
freopen("vigenere.out","w",stdout);
scanf("%s%s",k,m);
lm=strlen(m),lk=strlen(k);
for(int i=0;i<lk;i++)
if(k[i]>='a'&&k[i]<='z') key[i]=k[i]-'a';
else key[i]=k[i]-'A';
int j=0;
for(int i=0;i<lm;i++)
{
char tmp;
if(m[i]>='a'&&m[i]<='z') tmp='a',m[i]-='a';
else tmp='A',m[i]-='A';//用tmp储存大小写
m[i]-=key[j];
if(m[i]<0) m[i]+=26;
m[i]+=tmp;//再次转换成明文
j++;//密钥可能会被重复使用
if(j>=lk) j-=lk;
}
for(int i=0;i<lm;i++)
printf("%c",m[i]);
return 0;
}