P1189 SEARCH 题解

P1189 SEARCH 题解

应该是第一道没有看任何题解自己做出来的绿题了

Read more

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 ()

SP14932 LCA-Lowest Common Ancestor 超水题解

~~OI生涯中的第一篇题解 ~~

复习LCA的时候去查了查有什么题, 就发现了这道模板题.

因为我太菜, 不会写树上倍增, 就想有什么别的方法能过.

刚好发现一种朴素解法:

  • 先从 x 往上走到根,沿途会经过 x 所有的祖先,把它们用一个数组标记。
  • 再从 y 往上走到根,沿途会经过 y 所有的祖先,遇到的第一个被标记的点就是 x,y 的最近公共祖先。

看了一眼数据范围, N <= 1000. 这么水 (虽然有多组数据), 果断开搞.

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <cstring>
using namespace std;
int fa[1005], vis[1005];
int LCA(int x, int y){
memset(vis, 0, sizeof(vis));
while(x!=0){
vis[x]=1;
x=fa[x];
}
while(vis[y]==0){
y=fa[y];
}
return y;
}
int main(){
int T, cnt = 0;
cin >> T;
while(T--){
cnt++;
cout << "Case " << cnt << ":" << endl;
int n;
cin >> n;
for(int i = 1; i <= n; i++){
int m;
cin >> m;
for(int j = 1; j <= m; j++){
int tmp;
cin >> tmp;
fa[tmp] = i;
}
}
int Q;
cin >> Q;
while(Q--){
int a, b;
cin >> a >> b;
cout << LCA(a, b) << endl;
}
}
return 0;
}

没想到竟然AC了……

虽然正解树上倍增肯定要学习一个, 但这也不失为一种骗分~~~~暴力可行的技巧 (如果真的忘了怎么写).

#EOF.