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;
}

 

 

 

 

 

posted @ 2012-11-01 22:39  sorryhao  阅读(273)  评论(0)    收藏  举报