码迷,mamicode.com
首页 > 其他好文 > 详细

hdu1298(字典树)

时间:2018-08-01 22:21:54      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:==   释放   tin   空间   细节   opened   algorithm   const   它的   

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]=\0;
        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:\n",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\n",suffix[j].str);

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

        del(root);
        printf("\n");
    }
    return 0;
}
View Code

hdu1298(字典树)

标签:==   释放   tin   空间   细节   opened   algorithm   const   它的   

原文地址:https://www.cnblogs.com/shutdown113/p/9403773.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!