字典树练习

字典树相关习题练习

字典

字典

思路

字典树模板,注意数组大小

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
43
44
45
46
47
48
49
50
51
#include <bits/stdc++.h>
using namespace std;
//查询一些单词中某个前缀是否出现过
int tree[2000005][26]; //第一维代表字母的最大长度
int tot = 1;
int Insert(string s)
{
int rt = 1;
for(int i = 0; i < s.size(); ++i)
{
int x = s[i] - 'a';
if(!tree[rt][x])
{
tree[rt][x] = ++tot;
}
rt = tree[rt][x];
}
return 1;
}

int Find(string s) //查询是否出现过这个前缀
{
int rt = 1;
for(int i = 0; i < s.size(); ++i)
{
int x = s[i] - 'a';
if(!tree[rt][x]) return 0;
rt = tree[rt][x];
}
return 1;
}
int main()
{
int n, m;
cin >> n ;
string s;
for(int i = 1; i <= n; ++i)
{
cin >> s;
Insert(s);
}
cin >> m;
for(int i = 1; i <= m; ++i)
{
cin >> s;
if(Find(s))
cout << "YES" << '\n';
else
cout << "NO" << '\n';
}
}

统计难题

HDU - 1251

思路

依然是模板题,注意回车的判断。可以是getline,然后判断字符串长度为0,或者是gets == NULL,但是gets读入的是字符串

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
43
44
45
46
47
48
#include <bits/stdc++.h>
using namespace std;
//查询一些单词中某个单词的出现次数
int tree[2000005][26];
int tot = 1;
bool is[2100005];
int sum[2100005];
int insert(string s)
{
int rt = 1;
for(int i = 0; i < s.size(); ++i)
{
int x = s[i] - 'a';
if(!tree[rt][x])
{
tree[rt][x] = ++tot;
}
sum[tree[rt][x]]++;
rt = tree[rt][x];
}
is[rt] = 1;
}

int find(string s) //查询出现这个单词的次数
{
int rt = 1;
for(int i = 0; i < s.size(); ++i)
{
int x = s[i] - 'a';
if(!tree[rt][x]) return 0;
rt = tree[rt][x];
}
return sum[rt];
}
int main()
{
string s;
while(getline(cin, s))
{
if(s.size() == 0)
break;
insert(s);
}
while(cin >> s)
{
cout << find(s) << '\n';
}
}

Shortest Prefixes

POJ - 2001

题意

要求一个字符串的在能够唯一辨认的前提下的最小前缀。

思路

我们先把所有的单词放在字典树中,然后枚举每个单词,在每个单词中枚举每个字母,如果发现这个前缀的出现的次数等于1,那么就直接输出。

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <sstream>
#include <map>
#include <vector>
#include <stdio.h>
using namespace std;
int tot = 1;
int tree[20005][26];
bool vis[20005];
int sum[20005];
int insert(string s)
{
int rt = 1;
for(int i = 0; i < s.size(); ++i)
{
int x = s[i] - 'a';
if(!tree[rt][x])
tree[rt][x] = ++tot;
sum[tree[rt][x]]++;
rt = tree[rt][x];
}
}

int find(string s)
{
int rt = 1;
for(int i = 0; i < s.size(); ++i)
{
int x = s[i] - 'a';
if(!tree[rt][x])
return 0;
rt = tree[rt][x];
}
return sum[rt];
}
int main()
{
string s;
vector<string>V;
while(cin >> s)
{
insert(s);
V.push_back(s);
}
for(int i = 0; i < V.size(); ++i)
{
string s1;
int flag = 0;
for(int j = 0; j < V[i].size(); ++j)
{
s1 += V[i][j];
int num = find(s1);
if(num == 1)
{
flag = 1;
cout << V[i] << ' ' << s1 << '\n';
break;
}
}
if(!flag)
{
cout << V[i] << ' ' << s1 << '\n';
}
}

}