http://acm.hust.edu.cn/vjudge/problem/19224
题意:给定n个单词,一个字符串,问哪些单词在字符串中出现的次数最多。单词aba,文本ababa,则aba出现了2次。
题解:每找到一个记得要顺着fail找到所有单词。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<queue>
6 using namespace std;
7
8 const int N=160,L=1000010;
9 char s[L],ss[N][110];
10 int cnt[N];
11 int num,mx,n;
12 struct node{
13 int son[30];
14 int id,fail;
15 }a[N*110];
16 queue<int> q;
17 int maxx(int x,int y){return x>y ? x:y;}
18
19 void clear(int x)
20 {
21 a[x].id=a[x].fail=0;
22 memset(a[x].son,0,sizeof(a[x].son));
23 }
24
25 void trie(char *c,int id)
26 {
27 int l=strlen(c);
28 int x=0;
29 for(int i=0;i<l;i++)
30 {
31 int t=c[i]-'a'+1;
32 if(!a[x].son[t])
33 {
34 num++;
35 clear(num);
36 a[x].son[t]=num;
37 }
38 x=a[x].son[t];
39 }
40 a[x].id=id;
41 }
42
43 void buildAC()
44 {
45 while(!q.empty()) q.pop();
46 for(int i=1;i<=26;i++)
47 if(a[0].son[i]) q.push(a[0].son[i]);
48 while(!q.empty())
49 {
50 int x=q.front();q.pop();
51 int fail=a[x].fail;
52 for(int i=1;i<=26;i++)
53 {
54 int y=a[x].son[i];
55 if(y)
56 {
57 a[y].fail=a[fail].son[i];
58 q.push(y);
59 }
60 else a[x].son[i]=a[fail].son[i];
61 }
62 }
63 }
64
65 void find(char *c)
66 {
67 int l=strlen(c);
68 int x=0;
69 for(int i=0;i<l;i++)
70 {
71 int t=c[i]-'a'+1;
72 if(!a[x].son[t]) x=0;
73 else x=a[x].son[t];
74 int p=x;
75 while(p)
76 {
77 if(a[p].id) cnt[a[p].id]++;
78 p=a[p].fail;
79 }
80 }
81 }
82
83 int main()
84 {
85 freopen("a.in","r",stdin);
86 freopen("a.out","w",stdout);
87 while(1)
88 {
89 scanf("%d",&n);
90 if(!n) return 0;
91 num=mx=0;
92 clear(0);
93 memset(cnt,0,sizeof(cnt));
94 for(int i=1;i<=n;i++)
95 {
96 scanf("%s",ss[i]);
97 trie(ss[i],i);
98 }
99 buildAC();
100 scanf("%s",s);
101 find(s);
102 for(int i=1;i<=n;i++) mx=maxx(mx,cnt[i]);
103 printf("%d
",mx);
104 for(int i=1;i<=n;i++)
105 {
106 if(mx==cnt[i]) printf("%s
",ss[i]);
107 }
108 }
109 return 0;
110 }