原题网址:
http://acm.hust.edu.cn/vjudge/contest/124242#problem/E
额,其实这算不上是原题了,,但原题的网页我真的打不开,打开也看不太懂。。。
题解:
总体上是模板题,但有个小地方自己一开始凭借想象力做的。。。后来发现还是要好好读题。。。
卡点:题目说的是 no less than 也就是说,当这些都是0的时候,需要把所有的patterns都输出。
AC代码:
#include <iostream>
using namespace std;
#include <cstdio>
#include <string.h>
#include <queue>
#define maxnode 30001// maxnode 一般设置为 模式串数量*模式串长度
#define sigma 26
int num[153];
struct ac_automation{
int ch[maxnode][sigma];
//ch数组里存的都是位置信息,甚至包含了一些失效指针的信息。
int val[maxnode];
//int cnt[maxnode]; // count
int last[maxnode]; // 储存着最后在查询时需要向上层回溯的地址。
int f[maxnode]; // fail指针
int sz; // the num of the trie
int ans; // answer
void clear(){
sz = 1;
ans = 0;
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
//memset(cnt,0,sizeof(cnt));
}
int idx(char c){
return (int)(c-'a');
}
void insert(char s[],int v){
int u = 0;
for(int i = 0; s[i];i++){
int c = idx( s[i] );
if(!ch[u][c]){
memset(ch[sz],0,sizeof(ch[sz]));
ch[u][c] = sz++;
}
u = ch[u][c];
}
//cnt[u]++;
val[u] = v;
}
void build(){
queue<int> q;
f[0] = 0;
for(int i = 0;i < sigma;i++){
if(ch[0][i]){
f[ch[0][i]] = 0;
q.push(ch[0][i]);
last[ch[0][i]] = 0;
}
}
while(!q.empty()){
int now = q.front();
q.pop();
for(int i = 0;i < sigma ;i++){
int son = ch[now][i];
if(!son){
ch[now][i] = ch[f[now]][i];
continue;
}
q.push(son);
f[son] = ch[f[now]][i];
last[son] = val[f[son]] ? f[son] : last[f[son]];
}
}
}
void find(char *s){
int u = 0;
for(int i = 0;s[i];i++){
int c = idx(s[i]);
u = ch[u][c];
if(val[u]){
print(u);
}
else{
print(last[u]);
}
}
}
void print(int u){
if(u){
if(val[u])num[val[u]]++;
//ans += cnt[u];
//cnt[u] = 0;
print(last[u]);
}
}
}ac;
char sub[152][72];
char text[1001000];
int main(){
int n;
while(cin>>n,n){
memset(sub,0,sizeof(sub));
memset(num,0,sizeof(num));
ac.clear();
for(int i = 1;i <= n;i++){
scanf("%s",sub[i]);
ac.insert(sub[i],i);
}
ac.build();
scanf("%s",text);
ac.find(text);
int temp = 0;
for(int i = 1;i <= n;i++){
if(num[i] > temp)temp = num[i];
}
printf("%d\n",temp);
for(int i = 1;i <= n;i++){
if(num[i] == temp){
printf("%s\n",sub[i]);
}
}
}
}