HDU 1298 T9(字典树+dfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1298

题意:
模拟手机9键,给出每个单词的使用频率。现在给出按键的顺序,问每次按键后首字是什么(也就是要概率最大的)。

思路:

先建立字典树算出每个前缀出现的概率,然后dfs每种情况,选择概率大的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn = 1000*1000+5;
 6
 7 char s[105],ans[105],tmp[105];
 8
 9 int n, num = 0, p;
10 int pheno[8][4] = {{0,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}};
11 int key[8] = {3,3,3,3,3,4,3,4};
12
13 struct Trie
14 {
15     int son[26];
16     int cnt;
17 }t[maxn];
18
19 void init(int x)
20 {
21     t[x].cnt = 0;
22     memset(t[x].son,0,sizeof(t[x].son));
23 }
24
25 void insert(char* s, int d)
26 {
27     int u = 0, n = strlen(s);
28     for(int i=0;i<n;i++)
29     {
30         int c = s[i]-‘a‘;
31         if(!t[u].son[c])
32         {
33             num++;
34             init(num);
35             t[u].son[c] = num;
36         }
37         u = t[u].son[c];
38         t[u].cnt += d;
39     }
40 }
41
42 void dfs(int cur, int u, int len, char* s)
43 {
44      if(cur == len)
45      {
46          if(t[u].cnt > p)
47          {
48              p = t[u].cnt;
49              for(int i=0;i<len;i++)  ans[i] = tmp[i];
50              ans[len] = ‘\0‘;
51          }
52          return;
53      }
54      int k = s[cur]-‘2‘;
55      for(int i=0;i<key[k];i++)
56      {
57          int c = pheno[k][i];
58          if(!t[u].son[c])  continue;
59          tmp[cur] = ‘a‘+ c;
60          dfs(cur+1, t[u].son[c], len, s);
61      }
62 }
63
64 int main()
65 {
66     //freopen("in.txt","r",stdin);
67     int T;
68     scanf("%d",&T);
69     int kase = 0;
70     while(T--)
71     {
72         init(0);
73         scanf("%d",&n);
74         for(int i =0;i<n;i++)
75         {
76             scanf("%s%d",s,&p);
77             insert(s,p);
78         }
79         printf("Scenario #%d:\n",++kase);
80         int q; scanf("%d",&q);
81         while(q--)
82         {
83             scanf("%s",&s);
84             int len = strlen(s);
85             for(int i=0;i<len-1;i++)
86             {
87                 p = 0;
88                 dfs(0,0,i+1,s);
89                 if(p)  printf("%s\n",ans);
90                 else puts("MANUALLY");
91             }
92             if(q)  puts("");
93         }
94         printf("\n\n");
95     }
96     return 0;
97 }
时间: 2024-08-03 17:19:05

HDU 1298 T9(字典树+dfs)的相关文章

hdu 1298 T9(字典树+DFS)

题目连接:hdu 1298 T9 题目大意:模拟手机打字的猜想功能,根据概率,每按一个按键,输出可能性最高的串.先给定N个单词,以及频率, 然后是Q次询问,每次询问给定一个按按键的顺序,以1为终止. 解题思路:对单词表建立字典树,每个节点有一个经过的频率,这个频率是根据所有经过该节点的单词频率总和.然后 DFS搜索一遍,将答案保存在ans中. #include <cstdio> #include <cstring> #include <algorithm> using

HDU 1298 T9 ( 字典树 )

题意 : 给你 w 个单词以及他们的频率,现在给出模拟 9 键打字的一串数字,要你在其模拟打字的过程中给出不同长度的提示词,出现的提示词应当是之前频率最高的,当然提示词不需要完整的,也可以是 w 个单词出现最多次数的前缀. 分析 : 利用字典树存储这 w 个单词,然后给每一个结点的权值赋上其单词出现频率,接下来的工作就简单多了,只要暴力枚举模拟输入的数字键盘可能产生的单词组合,然后保存频率最高的那个即可! #include<string.h> #include<stdio.h> #

hdu1298 T9(手机输入法,每按一个数字,找出出现频率最高的字串,字典树+DFS)

Problem Description A while ago it was quite cumbersome to create a message for the Short Message Service (SMS) on a mobile phone. This was because you only have nine keys and the alphabet has more than nine letters, so most characters could only be

hdu 2846 Repository 字典树

// hdu 2846 Repository 字典树 // // 题目大意: // // 有n个字符串,m个待询问的字符串,问这些字符串里面以该询问的 // 字符串为子串的字符串有多少个 // // 解题思路: // // 字典树,将字符串的所有子串插入到字典树中,并设立一个No.标识 // 以免重计数.最后查询就好了 // // 感悟: // // 这题的数据量有点大,虽然p是10000,但是长度是20,单个字符串的 // 最大子串数粗略的估计是 20 * 20 ,所以开的空间也要比较大.开始

hdu1247Hat’s Words (组合单词,字典树+DFS)

Problem Description A hat's word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary. You are to find all the hat's words in a dictionary. Input Standard input consists of a number of lowercase words, on

hdu 1298 T9

字典树+DFS. #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<algorithm> using namespace std; struct shu{ int value, nn[27]; }node[250010]; int n, q, i, ii, v, zz, tott, anss, tt, ttt; const int INF =

HDU 1247 简单字典树

Hat’s Words Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7359    Accepted Submission(s): 2661 Problem Description A hat’s word is a word in the dictionary that is the concatenation of exactly

POJ 1451 T9 字典树+优先队列

题目来源:POJ 1451 T9 题意:给你一些单词 和优先值 然后当你按下数字的时候首先会出现哪个单词 就是我们平时手机的按键 思路:建一颗字典树 因为按一个数字对应多个字母 那么就有多种情况 我们要输出权值最大的一个 我用了优先队列 这里每个前缀的优先值是所有单词优先值的和 例如abc 5 abd 6 acd 7 那么a这个前缀的优先值是18 ab的优先值是11 #include <cstdio> #include <cstring> #include <queue>

HDU 2846 Repository(字典树,标记)

题目 字典树,注意初始化的位置~!!位置放错,永远也到不了终点了org.... 我是用数组模拟的字典树,这就要注意内存开多少了,,要开的不大不小刚刚好真的不容易啊.... 我用了val来标记是否是同一个串分解而来的,保存的是串的编号 num记录数目. //string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last); //把[first0,last0)之间的部分替换成[firs