題目鏈接: hdu 4287
題目大意: 手機打英文,先給出N個數字串表示按鍵的順序
M個單詞的詞典,詢問按下這些數字串分別會出現多少個詞典中的單詞
解題思路: 把單詞轉換成按鍵數字建成樹
最後一個數字結點w值記錄次數
查詢的時候根據數字遍歷字典樹
最後一個數字結點的w值既是答案
代碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 50100
struct snode{
int w;
int next[10];
}Tree[MAX*10];
int Index;
char ch[10],chnum[MAX][10];
int Find(char ch3) //字母對應手機的按鍵
{
if(ch3=='a'||ch3=='b'||ch3=='c')
return 2;
else if(ch3=='d'||ch3=='e'||ch3=='f')
return 3;
else if(ch3=='g'||ch3=='h'||ch3=='i')
return 4;
else if(ch3=='j'||ch3=='k'||ch3=='l')
return 5;
else if(ch3=='m'||ch3=='n'||ch3=='o')
return 6;
else if(ch3=='p'||ch3=='q'||ch3=='r'||ch3=='s')
return 7;
else if(ch3=='t'||ch3=='u'||ch3=='v')
return 8;
else
return 9;
}
void Insert(int Tlen) //遍歷建立樹
{
int i,S=0,child;
for(i=1;i<=Tlen;i++)
{
child=Find(ch[i-1]); //把單詞轉換成數字
if(Tree[S].next[child]==0)
{
if(i==Tlen)
Tree[Index].w++;
Tree[S].next[child]=Index++;
}
else
{
if(i==Tlen)
Tree[Tree[S].next[child]].w++;
}
S=Tree[S].next[child];
}
}
int Query(int k,int Tlen) //遍歷查詢
{
int i,S=0,child;
for(i=1;i<=Tlen;i++)
{
child=chnum[k][i-1]-'0';
if(Tree[S].next[child]!=0)
{
if(i==Tlen)
return Tree[Tree[S].next[child]].w;
S=Tree[S].next[child];
}
else //不存在此結點則返回0
return 0;
}
}
int main()
{
int n,m,t,i,j;
scanf("%d",&t);
while(t--)
{
Index=1;
memset(Tree,0,sizeof(Tree));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) //建立字典樹
{
scanf("%s",chnum[i]);
}
for(i=1;i<=m;i++)
{
scanf("%s",ch);
Insert(strlen(ch));
}
for(i=1;i<=n;i++) //查詢
{
printf("%d\n",Query(i,strlen(chnum[i])));
}
}
return 0;
}