【Codevs】1197 Vigenère密码 –2012年NOIP全国联赛提高组
打表?
找规律。
知道密文如何找明文?
我的做法:可以发现在表格中 相同的字母对应的 横纵坐标的值的和 是相同的。
如这一列 M 的 任意一个M上面的字母加对应的左面的字母的和都是相同的。
即 'M'+'A' == 'L'+'B' == 'K'+'C' ……
所以说密文和 key 全部转化为大写之后 s[i] + ‘A’ - ‘key[i]’ 就是所对应的字母;
还有就是, 这个表的每一个字母在斜着的时候都是有2列的。
所以说会直接减得话也会有奇怪的值出现,又因为找规律可知,只要把减出来不合法的值加上 26 就可以得到正确的对应的值。这样就可以了。
代码:
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1000 + 10;
char a[MAXN], key[MAXN];
int main()
{
scanf("%s", key+1);
scanf("%s", a+1);
int n = strlen(a+1);
int k = strlen(key+1);
for(int i = 1; i <= n; i ++)
{
int cnt = i%k;
if(cnt == 0)
cnt = k;
bool Az = false;
if(a[i] >= 'a' && a[i] <= 'z')
{
Az = true;
a[i] -= 32;
}
if(key[cnt] >= 'a' && key[cnt] <= 'z')
key[cnt] -= 32;
char ans = a[i] + 'A' - key[cnt];
while(ans < 'A')
ans += 26;
if(Az)
ans += 32;
printf("%c",ans);
}
return 0;
}