hdu1298(字典树)
Posted shutdown113
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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]=‘