题目链接:
https://www.luogu.org/problemnew/show/P3796
题目描述
有NN个由小写字母组成的模式串以及一个文本串TT。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串TT中出现的次数最多。
输入输出格式
输入格式:
输入含多组数据。
每组数据的第一行为一个正整数N,表示共有N个模式串, 1≤N≤150。
接下去N行,每行一个长度小于等于70的模式串。下一行是一个长度小于等于10^6的文本串T。
输入结束标志为N=0。
输出格式:
对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。
分析:
没啥好分析的,就是板子。结构体直接多一个成员变量order,用来记录到当前结点的是第几个串,如果是0就代表没有这个串。在ac匹配的时候拿一个ans数组存一下出现次数,最后统计一下输出。完结撒花啦!
实现代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<map>
#include<stack>
#include<string>
#include<algorithm>
#include<cmath>
#define rg register
#define il inline
using namespace std;
typedef unsigned long long ll;
typedef unsigned long long ll;
ll read(){
ll ans=0,flag=1;char ch;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') flag=-1;
ans=ch^48;
while((ch=getchar())>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+(ch^48);
return flag*ans;
}
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
struct trie{
int ch[26];
int fail;
int ord;
}ac[12000];
int now=0;
void insertstr(int i,char *s){
int root=0;
while(*s){
if(ac[root].ch[*s-'a']==0){
ac[root].ch[*s-'a']=++now;
}
root=ac[root].ch[*s-'a'];
s++;
}
ac[root].ord=i+1;
}
il void getfail(){
queue<int>q;
for(rg int i=0;i<26;i++){
if(ac[0].ch[i]){
ac[ac[0].ch[i]].fail=0;
q.push(ac[0].ch[i]);
}
}
while(!q.empty()){
int now=q.front();
q.pop();
for(rg int i=0;i<26;i++){
if(ac[now].ch[i]){
ac[ac[now].ch[i]].fail=ac[ac[now].fail].ch[i];
q.push(ac[now].ch[i]);
}
else
ac[now].ch[i]=ac[ac[now].fail].ch[i];
}
}
}
int ans[160];
void aczdj(char *s){
int now=0;
while(*s){
now=ac[now].ch[*s-'a'];
for(int i=now;i;i=ac[i].fail){
if(ac[i].ord)
ans[ac[i].ord]++;
}
s++;
}
}
char longbuff[1000005];
int main()
{
char buff[160][80];
int n;
while(cin>>n&&n){
memset(ac,0,sizeof ac);
memset(ans,0,sizeof ans);
now=0;
for(rg int i=0;i<n;i++){
scanf("%s",buff[i]);
insertstr(i,buff[i]);
}
scanf("%s",longbuff);
getfail();
aczdj(longbuff);
int m=0;
for(rg int i=1;i<=n;i++)
m=max(ans[i],m);
printf("%d\n",m);
for(rg int i=1;i<=n;i++){
if(ans[i]==m)
puts(buff[i-1]);
}
//puts("");
}
return 0;
}