题目:http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=329
在hust 上不知道为什么交UVAlive的题目全是错的。。我在安徽大学上提交通过,但在hust上uvalive的题目都交不过。
AC自动机。这题很好啊,找了很久的错误都才找到,关键要注意两个方面,一个是模版串可能有重复的,在输出的时候需要全部输出,二是在查询的时候
while(temp!=root&&temp->cnt>=0){ // //这里要设置成大于等于,因为进入这里可能只是个中间串,但是在跳转的时候可能跳到模版串的末尾。
for(int j=0;j<(temp->id.size());j++)
ans[ temp->id[j] ]++;
temp=temp->fail;
}
#include<cstdio>
#include<cstring>
#include<map>
#include<string>
#include<vector>
using namespace std;
char s[200][100];
char str[1100000];
int ans[200];
int head,tail;
struct node{
node *fail;
node *next[26];
int cnt; vector<int > id;
node() { cnt=0; id.clear(); fail=NULL; memset(next,NULL,sizeof(next)); }
} *q[5000000];
void insert(node *root,char str[],int id){
int i=0,index; node *p=root;
while(str[i]){
index=str[i]-'a';
if(p->next[index]==NULL) p->next[index]= new node();
p=p->next[index];
i++;
}
p->cnt++; p->id.push_back(id);
}
void build_ac(node *root){
root->fail=NULL;
q[head++]=root;
while(head!=tail){
node *temp=q[tail++];
node *p=NULL;
for(int i=0;i<26;i++){
if(temp->next[i]!=NULL){
if(temp==root) temp->next[i]->fail=root;
else{
p=temp->fail;
while(p!=NULL){
if(p->next[i]!=NULL){
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL) temp->next[i]->fail=root;
}
q[head++]=temp->next[i];
}
}
}
}
void query(node *root){
int i=0,index; node *p=root;
int len=strlen(str);
for(int i=0;i<len;i++){
index=str[i]-'a';
while(p->next[index]==NULL&&p!=root) p=p->fail;
p=p->next[index];
p=(p==NULL)?root:p;
node *temp=p;
while(temp!=root&&temp->cnt>=0){
for(int j=0;j<(temp->id.size());j++)
ans[ temp->id[j] ]++;
temp=temp->fail;
}
}
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
if(n==0) break;
memset(ans,0,sizeof(ans));
head=tail=0;
node *root = new node();
for(int i=0;i<n;i++) scanf("%s",s[i]),insert(root,s[i],i+1);
build_ac(root);
scanf("%s",str);
query(root);
int max=0;
for(int i=1;i<=n;i++) if(ans[i]>max) max=ans[i];
printf("%d\n",max);
for(int i=1;i<=n;i++){
if(ans[i]==max){
printf("%s\n",s[i-1]);
}
}
}
return 0;
}