题目描述:戳这里
题解:AC自动机简单版的题解
这题相较于那一题只是改变了一下求的东西,我们只要稍加改动,就能AC。
代码如下:
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int maxn=10505,maxm=1e6+5;
int n,tot,ans[maxn],que[maxn];
char s[150][75],s1[maxm];
struct dyt{
int end,nxt[28],fail;
}tree[maxn];
void insert(char s[75],int id){
int now=0,len=strlen(s);
for (int i=0;i<len;i++){
int x=s[i]-'a'+1;
if (!tree[now].nxt[x]) tree[now].nxt[x]=++tot;
now=tree[now].nxt[x];
}
tree[now].end=id;
}
void build(){
int head=0,tail=0;
for (int i=1;i<=26;i++)
if (tree[0].nxt[i])
que[++tail]=tree[0].nxt[i],tree[tree[0].nxt[i]].fail=0;
while (head!=tail) {
head++; int x=que[head];
for (int i=1;i<=26;i++)
if (tree[x].nxt[i]) {
tree[tree[x].nxt[i]].fail=tree[tree[x].fail].nxt[i];
que[++tail]=tree[x].nxt[i];
} else tree[x].nxt[i]=tree[tree[x].fail].nxt[i];
}
}
void get(){
int now=0,len=strlen(s1);
for (int i=0;i<len;i++) {
now=tree[now].nxt[s1[i]-'a'+1];
for (int j=now;j;j=tree[j].fail) {
ans[tree[j].end]++;
}
}
int sum=0;
for (int i=1;i<=n;i++) if (ans[i]>sum) sum=ans[i];
printf("%d\n",sum);
for (int i=1;i<=n;i++)
if (ans[i]==sum) printf("%s\n",s[i]);
}
int main(){
while (1) {
scanf("%d",&n);
if (n==0) break;
tot=0; memset(ans,0,sizeof(ans));
for (int i=0;i<=10500;i++) {
tree[i].end=tree[i].fail=0;
memset(tree[i].nxt,0,sizeof(tree[i].nxt));
}
for (int i=1;i<=n;i++) {
scanf("%s",s[i]);
insert(s[i],i);
}
build();
scanf("%s",s1);
get();
}
return 0;
}