动态建树加深搜之——模仿手机九键输入法

题目:poj1451

题意:给你一个词语出现次数的表,然后给你一个输入的数字串,每一步输出它最可能出现的单词。没有了就输出一个东西。

解答:建一个字典树,然后深度遍历这课树。每遍历一步都要记录下当前的字符串。最后输出。要记录当前位置最大值。如果该步没有更新过最大值说明这一步找不到字母了。

           用一个str数组记录当前的串。用k记录搜到多长了。注意回溯!还有,不管更新不更新答案,只要有就要继续往下搜。

#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 1010;
const int maxn = 110;
const int sonnum = 26,base = 'a';
int dir[11] = {0,0,0,3,6,9,12,15,19,22,26};
int Max[maxn];
char ans[maxn][maxn],str[maxn],numarr[maxn];
int n,m,k,p,len;
struct Trie
{
    int num;
    bool terminal;
    struct Trie *son[sonnum];
};
Trie *NewTrie()
{
    Trie *temp = new Trie;
    temp -> num = 1;
    for(int i = 0;i < sonnum;i++)
    {
        temp -> son[i] = NULL;
    }
    return temp;
}
void Insert(Trie *pnt,char *s,int a)
{
    Trie *tmp = pnt;
    int len1 = strlen(s);
    for(int i = 0;i < len1;i++)
    {
        if(tmp -> son[s[i]-base] == NULL)
        {
            tmp -> son[s[i]-base] = NewTrie();
            tmp -> son[s[i]-base] -> num += (a - 1);
        }
        else
            tmp -> son[s[i]-base] -> num += a;
        tmp = tmp -> son[s[i]-base];
    }
}
void dfs(Trie *pnt,int step)
{
    int start = dir[numarr[step]];
    int End = dir[numarr[step]+1];
    Trie *tmp = pnt;
    for(int i = start;i < End;i++)
    {
        if(tmp -> son[i] == NULL)
            continue;
        k++;//k表示当前的深度
        str[k] = i + base;
        if(tmp -> son[i] -> num > Max[k])//如果最大则更新答案
        {
            Max[k] = tmp -> son[i] -> num;
            str[k+1] = 0;
            strcpy(ans[k],str);
        }
        if(k != len-1)
            dfs(tmp->son[i],step+1);
        k--;
    }
}
int main()
{
    int T;
    char input[MAXN];
    scanf("%d",&T);
    for(int i = 1;i <= T;i++)
    {
        scanf("%d",&n);
        Trie *tree = NewTrie();
        for(int j = 1;j <= n;j++)
        {
            scanf("%s %d",input,&p);
            Insert(tree,input,p);
        }
        scanf("%d",&m);
        printf("Scenario #%d:\n",i);
        while(m--)
        {
            scanf("%s",numarr);
            len = strlen(numarr);
            len--;
            k = -1;
            memset(Max,-1,sizeof(Max));///
            dfs(tree,0);
            int w;
            for(w = 0;w < len;w++)
            {
                if(Max[w]!=-1)
                {
                    printf("%s\n",ans[w]);
                }
                else
                    break;
            }
            for(int j = w;j < len;j++)
                printf("MANUALLY\n");
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}




你可能感兴趣的:(字典树)