NOIP2012TG D1T1 Vigenère密码 题解

考前发一波题解

去年输在了那道格雷码上, 今年吸取教训, 狂刷历年tg d1t1, 其中碰到了这道字符串好题.

看到中间给的加密规则表, 立马想到可以打表, 就先打了个表.

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
26
27
28
string abc[26]= {
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"BCDEFGHIJKLMNOPQRSTUVWXYZA",
"CDEFGHIJKLMNOPQRSTUVWXYZAB",
"DEFGHIJKLMNOPQRSTUVWXYZABC",
"EFGHIJKLMNOPQRSTUVWXYZABCD",
"FGHIJKLMNOPQRSTUVWXYZABCDE",
"GHIJKLMNOPQRSTUVWXYZABCDEF",
"HIJKLMNOPQRSTUVWXYZABCDEFG",
"IJKLMNOPQRSTUVWXYZABCDEFGH",
"JKLMNOPQRSTUVWXYZABCDEFGHI",
"KLMNOPQRSTUVWXYZABCDEFGHIJ",
"LMNOPQRSTUVWXYZABCDEFGHIJK",
"MNOPQRSTUVWXYZABCDEFGHIJKL",
"NOPQRSTUVWXYZABCDEFGHIJKLM",
"OPQRSTUVWXYZABCDEFGHIJKLMN",
"PQRSTUVWXYZABCDEFGHIJKLMNO",
"QRSTUVWXYZABCDEFGHIJKLMNOP",
"RSTUVWXYZABCDEFGHIJKLMNOPQ",
"STUVWXYZABCDEFGHIJKLMNOPQR",
"TUVWXYZABCDEFGHIJKLMNOPQRS",
"UVWXYZABCDEFGHIJKLMNOPQRST",
"VWXYZABCDEFGHIJKLMNOPQRSTU",
"WXYZABCDEFGHIJKLMNOPQRSTUV",
"XYZABCDEFGHIJKLMNOPQRSTUVW",
"YZABCDEFGHIJKLMNOPQRSTUVWX",
"ZABCDEFGHIJKLMNOPQRSTUVWXY"
};

然后开始写.

中间遇到了各种各样的小问题. 比如忘了需要把得到的ascii码在这里转换为下标, 再比如当中出现了奇怪的字符, 调了好一会儿才调对.

等到终于能用了, 测了测样例才发现, 原来刚才写的其实是加密…… 为了改成解密就在每一行里枚举一遍找对应的字符获取明文. 其实本来可以通过改打表的方式实现, 但懒得写了 (

最后提交, AC, 24ms.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <cmath>
using namespace std;
string abc[26] = (...)
int main(){
string k, s;
cin >> k;
cin >> s;
for(int i = 0; i <= 5; i++) k += k;
for(int i = 0; i < s.length(); i++){
int K= (k[i] >=65 && k[i]<=90) ? (int)(k[i]-65):(int)(k[i]-97);
char S = (s[i] >= 97 && s[i] <= 122) ? s[i]-32:s[i];
for(int j = 0; j < 26; j++){
if(abc[K][j]==S){
if(s[i] >= 97 && s[i] <= 122) cout << (char) (j+97);
else cout << (char) (j+65);
break;
}
}
}
return 0;
}

原谅我奇怪的码风

下午rp++, 争取 AC T1 ()