POJ 1451 T9(字典树+bfs)
2015-08-05 20:19
344 查看
背景:为了方便九宫格手机用户发短信,希望在用户按键时,根据提供的字典(给出字符串和频数),给出各个阶段最有可能要打的单词。
注意:hell的权值为hell hello hellmoun 的权值和。
即一个字符串前缀的概率等于所有前缀之和。
还有就是一个单词在输入法中,这个单词的所有前缀也在输入法中。
mymy codecode
题意:
首先给出的是字典,每个单词有一个出现频率。然后给出的是询问,每个询问有一个数字字符串,代表在手机上按了哪些键,以1结束。问按键的过程中最可能出现的单词分别是哪些。注意:hell的权值为hell hello hellmoun 的权值和。
即一个字符串前缀的概率等于所有前缀之和。
还有就是一个单词在输入法中,这个单词的所有前缀也在输入法中。
解析:
字典树来搞这道题目,可以把所有的字符串都插入字典树中,然后bfs这颗字典树,找到当前层权最大的节点,并输出该路径。mymy codecode
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <queue> using namespace std; const int maxnode = 1005 * 105; const int sigma_size = 26; string T9[10]; int ch[maxnode][sigma_size]; int fa[maxnode]; char alpha[maxnode]; int val[maxnode]; int idx(int c) { return c - 'a'; } struct Trie { int sz; void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } Trie() { clear(); } void insert(char *s, int p) { int u = 0, n = strlen(s); for(int i = 0; i < n; i++) { int c = idx(s[i]); if(!ch[u][c]) { memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; fa[sz] = u; alpha[sz] = c + 'a'; ch[u][c] = sz++; } u = ch[u][c]; val[u] += p; } } } trie; void init() { T9[0] = ""; T9[1] = ""; T9[2] = "abc"; T9[3] = "def"; T9[4] = "ghi"; T9[5] = "jkl"; T9[6] = "mno"; T9[7] = "pqrs"; T9[8] = "tuv"; T9[9] = "wxyz"; } void dfs(int u) { if(u == 0) return ; dfs(fa[u]); putchar(alpha[u]); } struct Node { int u, step; Node(int u, int step) : u(u), step(step) {} }; int bfs(char* s, int len) { queue<Node> que; que.push(Node(0, -1)); int maxp = -1, ret = -1; int u, step; while(!que.empty()) { Node front = que.front(); que.pop(); u = front.u, step = front.step; if(step > len) continue; if(step == len && val[u] > maxp) { maxp = val[u]; ret = u; } int num = s[step+1] - '0'; for(int i = 0; i < T9[num].size(); i++) { int c = idx(T9[num][i]); if(ch[u][c]) { int v = ch[u][c]; que.push(Node(v, step+1)); } } } return ret; } int n, m, p; char str[105]; int main() { init(); int T, cas = 1; scanf("%d", &T); while(T--) { trie.clear(); scanf("%d", &n); while(n--) { scanf("%s%d", str, &p); trie.insert(str, p); } scanf("%d", &m); printf("Scenario #%d:\n", cas++); while(m--) { scanf("%s", str); int len = strlen(str); for(int i = 0; str[i] != '1'; i++) { int u = bfs(str, i); if(u == -1) { puts("MANUALLY"); }else { dfs(u); puts(""); } }puts(""); }puts(""); } return 0; }
相关文章推荐
- hdu 5348 MZL's endless loop dfs
- 华为机试 地铁换乘问题(最短路径算法)
- /etc/grub.conf
- 7 天玩转 ASP.NET MVC — 第 4 天
- 海盗分赃
- What is a BSP Application?
- DOM解析xml文件
- 【读书笔记】iOS-防止通讯协议被轻易破解的方法
- 【BZOJ1026】windy数题解
- [leetcode 242]Valid Anagram
- bss段、data段、text段、堆(heap) 和 栈(stack)
- 【读书笔记】iOS-防止通讯协议被轻易破解的方法
- 7 天玩转 ASP.NET MVC — 第 4 天
- iOS之UIImageView帧动画
- fzu1752(坑!!!)
- 把BaseAdapter内部类搬运出来单独形成一个类的方法时,出现的错误
- zedboard的板级支持包GPIO例子
- 广度搜索(2)
- zoj 2100 Seeding
- Hadoop-HBASE 热添加新节点