1. 程式人生 > >hdu1298(字典樹)

hdu1298(字典樹)

eno aps class 按鍵 -a pen 代碼 lan max

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(字典樹)