題面:
統(tǒng)計難題
Time Limit: 4000/2000 MS (Java/Others)????Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 25921????Accepted Submission(s): 10560
Problem Description
Ignatius最近遇到一個難題,老師交給他很多單詞(只有小寫字母組成,不會有重復的單詞出現),現在老師要他統(tǒng)計出以某個字符串為前綴的單詞數量(單詞本身也是自己的前綴).
?
Input
輸入數據的第一部分是一張單詞表,每行一個單詞,單詞的長度不超過10,它們代表的是老師交給Ignatius統(tǒng)計的單詞,一個空行代表單詞表的結束.第二部分是一連串的提問,每行一個提問,每個提問都是一個字符串.
注意:本題只有一組測試數據,處理到文件結束.
?
Output
對于每個提問,給出以該字符串為前綴的單詞的數量.
?
Sample Input
banana
band
bee
absolute
acm
ba
b
band
abc
?
Sample Output
2
3
1
0
題意:
? ?額,中文大家都懂。
解題:
? ? 字典樹裸題,val值統(tǒng)計經過該點的字母數量。
代碼:
#include#include#include#includeusing?namespace?std; struct?Trie { //用來儲存該節(jié)點的26個字母下標,ch的第一維要注意,要開大,不然會T? int?ch[1000010][26]; //val數組一般用來存儲權值,視題目靈活運用,sz是當前節(jié)點數量 int?val[1000010],sz; //初始化 void?init() { sz=1; memset(ch[0],0,sizeof(ch[0])); } //插入一條單詞 void?insert(string?s) { //u是節(jié)點編號,并不是層數 int?u=0,len=s.length(); for(int?i=0;i<len;i++) { //取下標 int?c=(s[i]-'a'); //如果該節(jié)點不存在,創(chuàng)建該節(jié)點 if(!ch[u][c]) { //真的是相當的省 memset(ch[sz],0,sizeof(ch[sz])); //因為剛創(chuàng)建所以為1 val[sz]=1; //給該節(jié)點分配編號 ch[u][c]=sz++; //下移 u=ch[u][c]; } //已經存在了 else { ??//下移,并計數值加一 ??u=ch[u][c]; ??????val[u]++; } } } //查詢前綴 int?query(string?s) { int?len=s.length(),u=0,c; //不斷下移,直至移到給定的前綴的最后一個單詞 bool?sign=true; for(int?i=0;i<len;i++) { ???c=s[i]-'a'; ???if(ch[u][c]) ?????????????u=ch[u][c]; ???????????else ???????????{ ??????????????sign=false; ??????????????break; ???????????} } if(sign) ??????????return?val[u]; ????????else ??????????return?0; } }; Trie?T; int?main() { ????????string?s; ????????T.init(); ????????while(getline(cin,s)) ????????{ ???????????if(s=="")break; ???????????T.insert(s); ????????} ????????while(getline(cin,s)) ????????{ ???????????cout<<T.query(s)<<endl; ????????} ????return?0; }