HDU 4287 Intelligent IME
题目大意:
给出的按键方法(数字)可以匹配多少个字符串
解法:
这道题一开始我考虑的是字典树。诚然,字典树可以过本题而且效率不低。不过很快队友发现题目给出的数字最多才6位。
题目一下子就简化了。hash每个数字键可能出现的字符,开一个10^7的数组记录每个按键方案的匹配次数。
输入字符串时,通过上面的hash数组,将其还原为数字表示,然后用O(1)的方法更新相应按键方法的匹配次数即可。
一处内存优化,记录匹配次数的数组可以用short类型,数据保证不超过5000。最后15ms过了本题。
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 5 struct Node { 6 int tmp, id; 7 } word[5005]; 8 short cnt[1000000]; 9 bool has[15][150]; 10 11 void init() { 12 has[2]['a'] = has[2]['b'] = has[2]['c'] = true; 13 has[3]['d'] = has[3]['e'] = has[3]['f'] = true; 14 has[4]['g'] = has[4]['h'] = has[4]['i'] = true; 15 has[5]['j'] = has[5]['k'] = has[5]['l'] = true; 16 has[6]['m'] = has[6]['n'] = has[6]['o'] = true; 17 has[7]['p'] = has[7]['q'] = has[7]['r'] = has[7]['s'] = true; 18 has[8]['t'] = has[8]['u'] = has[8]['v'] = true; 19 has[9]['w'] = has[9]['x'] = has[9]['y'] = has[9]['z'] = true; 20 } 21 22 int main() { 23 init(); 24 int T; 25 scanf("%d", &T); 26 while (T--) { 27 int n, m; 28 scanf("%d%d", &n, &m); 29 for (int i = 0; i < n; i++) { 30 scanf("%d", &word[i].tmp); 31 word[i].id = i; 32 } 33 memset(cnt, 0, sizeof(cnt)); 34 getchar(); 35 for (int i = 0; i < m; i++) { 36 char input[5005]; 37 gets(input); 38 int ans = 0; 39 for (int j = 0; input[j]; j++) { 40 int k; 41 for (k = 2; k < 10; k++) { 42 if (has[k][input[j]] == true) { 43 break; 44 } 45 } 46 ans = ans * 10 + k; 47 } 48 cnt[ans]++; 49 } 50 for (int i = 0; i < n; i++) { 51 printf("%d\n", cnt[word[i].tmp]); 52 } 53 } 54 return 0; 55 }
1 | dgsrz@bilibili | 15MS | 2240K | 1506B | C++ | 2012-09-09 20:03:12 |