HDU 4287 Intelligent IME(字典树)

来源:互联网 发布:家用中央空调知乎 编辑:程序博客网 时间:2024/04/27 19:08

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4287


题意:根据手机的输入法可以知道

2:a,b,c

3:d,e,f

4:g,h,i

5:j,k,l

6:m,n,o

7:p,q,r,s

8:t,u,v

9:w,x,y,z

先给n个串由数字构成,然后m个串由字母构成。

对于每个数字串,判断可以包含几个字母串,并输出。


思路:用数字串建字典树,在每个数字串的结尾的节点记录好该数字串包含字母串的个数。预处理好每个字母所属于的数字,然后在字典树中查找字母串,并在数字串的结尾节点计数。


代码:

#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>#include <string>#include <vector>using namespace std;#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1#define ceil(x, y) (((x) + (y) - 1) / (y))const int SIZE = 10;const int N = 5e5 + 10;const int INF = 0x7f7f7f7f;struct Trie {int val[SIZE];int count;};int sz;int len[SIZE] = {3, 3, 3, 3, 3, 4, 3, 4};int vis[SIZE * 3];Trie pn[N];string str[N];int newnode() {memset(pn[sz].val, 0, sizeof(pn[sz].val));pn[sz].count = 0;return sz++;}void init() {sz = 0;newnode();memset(vis, false, sizeof(vis));int k = 0;for (int i = 0; i < 8; i++)for (int j = 0; j < len[i]; j++)vis[k++] = i + 2;}void insert(string s) {int u = 0;for (int i = 0; i < s.size(); i++) {int idx = s[i] - '0';if (!pn[u].val[idx]) {pn[u].val[idx] = newnode();}u = pn[u].val[idx];}}void findpre(string s) {int u = 0;for (int i = 0; i < s.size(); i++) {int idx = s[i] - 'a';if (!pn[u].val[vis[idx]])return ;u = pn[u].val[vis[idx]];}pn[u].count++;}int findstr(string s) {int u = 0;for (int i = 0; i < s.size(); i++) {int idx = s[i] - '0';u = pn[u].val[idx];}return pn[u].count;}int main() {int t_case;cin >> t_case;for (int i_case = 1; i_case <= t_case; i_case++) {int n, m;cin >> n >> m;init();for (int i = 0; i < n; i++) {cin >> str[i];insert(str[i]);}for (int i = 0; i < m; i++) {string t;cin >> t;findpre(t);}for (int i = 0; i < n; i++)cout << findstr(str[i]) << endl;}return 0;}


0 0
原创粉丝点击