hdu1298(字典树)

T9

题意:

  给出每个单词的权值,现在使用九键拼音,根据用户的按键弹出权值最大单词,如果答案有多个,弹出字典序最小的,问当用户按下一个键时,应该弹出哪个单词。规定每次按键的值一定是1-9的数字,如果为1不用处理。对于一系列按键,如果字典中没有与之对应的单词,输出“MANUALLY”。如果单词a是单词b的前缀,那么a的权值为两者的累加和,例如对于hel 2,hello 4,hel的权值为2+4=6。如果一个单词在字典中,那么它的前缀也可以认为是在字典中,并且对应的权值为该字母的权值。

分析:

  首先根据给出的单词建立一颗字典树,根据题目意思,权值是可以累加的,并且一个单词的前缀也是在字典中的,所以我们在插入一个单词时,所经过的节点都需加上该单词的权值。当我们进行按键的查询时,用dfs枚举出按键对应的所有的单词,计算出每一个单词在字典树中的权值,取其中权值最大的单词输出即可。主要是注意一下细节的处理吧,注意不要随便释放节点的空间(Re在这里好多次),按键为1的处理,在字典树中找不到对应单词的处理。

代码:

#include <map>
#include <queue>
#include <math.h>
#include <string>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>

using namespace std;
#define ll long long
#define ull unsigned long long
#define cls(x) memset(x,0,sizeof(x))
#define clslow(x) memset(x,-1,sizeof(x))

const int wordLen=200;
const int maxn=1e5+100;

int n,q,T,add;

char s[wordLen],t[wordLen];
char mp[]={' ',' ','a','d','g','j','m','p','t','w'};

struct TrieNode {
    int weight;
    TrieNode* nex[26];
};
TrieNode* root;

struct Suffix {
    int maxw;
    char* str;
};
Suffix suffix[wordLen];

TrieNode* build()
{
    TrieNode* node=new TrieNode;
    node->weight=0;
    cls(node->nex);
    return node;
}

void Insert(char* s,int add)
{
    int len=strlen(s);
    TrieNode* node=root;
    for(int i=0;i<len;i++){
        int x=s[i]-'a';
        if(node->nex[x]==NULL){
            node->nex[x]=build();
        }
        node=node->nex[x];
        node->weight+=add;
    }
}

int Find(char* s)
{
    int len=strlen(s);
    TrieNode* node=root;
    for(int i=0;i<len;i++){
        int x=s[i]-'a';
        if(node->nex[x]==NULL){
            return 0;
        }
        node=node->nex[x];
    }
    return node->weight;
}

void del(TrieNode* node)
{
    for(int i=0;i<26;i++){
        if(node->nex[i]!=NULL){
            del(node->nex[i]);
        }
    }
    free(node);
}

void dfs(char* s,int pos)
{
    if(s[pos]=='1') return;

    int len=3;
    char ch=mp[s[pos]-'0'];
    if(s[pos]=='7'||s[pos]=='9')    len=4;

    for(char i=ch;i<ch+len;i++){
        t[pos]=i;
        t[pos+1]='';
        int reval=Find(t);
        if(reval==0)    continue;
//        cout<<reval<<" "<<t<<endl;
        if(reval>suffix[pos].maxw){
            suffix[pos].str=new char[strlen(t)];
            strcpy(suffix[pos].str,t);
            suffix[pos].maxw=reval;
        }
        dfs(s,pos+1);
    }
    if(suffix[pos].maxw==0){
        int slen=strlen(s);
        for(int i=pos;i<slen-1;i++){
            suffix[i].maxw=0;
            suffix[i].str=new char[10];
            strcpy(suffix[i].str,"MANUALLY");
        }
    }
}

int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%d",&T);
    for(int kase=1;kase<=T;kase++){
        printf("Scenario #%d:
",kase);

        root=build();
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s%d",s,&add);
            Insert(s,add);
        }

        scanf("%d",&q);
        for(int i=1;i<=q;i++){
            scanf("%s",s);

            dfs(s,0);

            int slen=strlen(s);
            for(int j=0;j<slen-1;j++){
                printf("%s
",suffix[j].str);

                suffix[j].maxw=0;
            }
            printf("
");
        }

        del(root);
        printf("
");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/shutdown113/p/9403773.html