hihoCoder#1014 Trie树 (前缀树)
题目大意:给一本有n个单词的词典,有m次询问,每次询问的是该词典中有多少个单词有共同的某个前缀。
题目分析:在添加单词建立trie的时候,每经过一个节点就意味着该节点和它的各级祖先节点是某个单词的前缀,这样就可以在建立trie的同时统计单词个数。
代码如下:
# include<iostream> # include<cstdio> # include<cstring> # include<vector> # include<queue> # include<list> # include<set> # include<map> # include<string> # include<cmath> # include<cstdlib> # include<algorithm> using namespace std; # define LL long long const int N=1005; const int INF=1000000000; const LL oo=0x7fffffffffffffff; const double eps=1e-10; string p; int len[N*1000]; int cnt; int tr[N*1000][26]; void insert() { int u=0; int n=p.size(); for(int i=0;i<n;++i){ int c=p[i]-'a'; if(!tr[u][c]){ memset(tr[cnt],0,sizeof(tr[cnt])); tr[u][c]=cnt++; } u=tr[u][c]; ++len[u]; } } int query() { int n=p.size(); int u=0; for(int i=0;i<n;++i){ if(!tr[u][p[i]-'a']) return 0; u=tr[u][p[i]-'a']; } return len[u]; } int main() { int n,m; while(~scanf("%d",&n)) { cnt=1; memset(len,0,sizeof(len)); memset(tr,0,sizeof(tr)); while(n--) { cin>>p; insert(); } scanf("%d",&m); while(m--) { cin>>p; printf("%d\n",query()); } } return 0; }