HDU 1298(T9)
题目链接地址:http://acm.hdu.edu.cn/showproblem.php?pid=1298
/*字典树
Date: 2012/11/1
先用字典树存放单词,然后通过数字字符串枚举选择权值最大的那个单词即可
注意枚举的时候要剪枝,不过也是很简单的剪枝
*/
#include<iostream> using namespace std; #define maxn 101 struct Trie { int n; Trie *next[26]; Trie() { n = 0; memset(next,0,sizeof(next)); } }; int t,p,q,maxnum; char s[maxn],ans[maxn],num[maxn]; char key[10][5] = { {""}, {""},{"abc1"},{"def1"}, {"ghi1"},{"jkl1"},{"mno1"}, {"pqrs"},{"tuv1"},{"wxyz"} }; void Insert(Trie *root, char s[],int num) { Trie *p = root; for(int i = 0; s[i]; i++) { int j = s[i] - 'a'; if(p->next[j] == NULL) p->next[j] = new Trie(); p = p->next[j]; p->n += num; } } int Find(Trie *root,char s[]) { Trie *p= root; for(int i = 0; s[i]; i++) { int j = s[i] - 'a'; if(p->next[j] == NULL) return -1; p = p->next[j]; } return p->n; } void dfs(Trie *root,int i,int len) { if(i == len) { s[len] = 0; int t = Find(root,s); if(t > maxnum) { maxnum = t; strcpy(ans,s); } } else { for(int k = 0; k < 4; k++) { int j = num[i] - '0'; if(key[j][k] != '1') { s[i] = key[j][k]; s[i+1] = 0; int t = Find(root,s); //剪枝 if(t <= maxnum) continue; dfs(root,i+1,len); } } } } void Delete(Trie *root) //释放空间 { for(int i = 0; i < 26; i++) if(root->next[i] != NULL) { Delete(root->next[i]); delete root->next[i]; } } int main() { //freopen("1003.txt","r",stdin); int count = 1; scanf("%d",&t); while(t--) { int i,j; Trie *root = new Trie(); printf("Scenario #%d:\n",count++); scanf("%d",&p); while(p--) { scanf("%s%d",s,&j); Insert(root,s,j); } scanf("%d",&q); while(q--) { scanf("%s",num); for(i = 0; num[i] != '1'; i++) { maxnum = -1; dfs(root,0,i+1); if(maxnum == -1) printf("MANUALLY\n"); else printf("%s\n",ans); } printf("\n"); } printf("\n"); Delete(root); } return 0; }

浙公网安备 33010602011771号