这到底是怎样的一道题?输入里面就没要求要有文件结束符,尼玛,不加文件结束符不让过,靠,真坑。。。。这道题也是考察AC自动机的,AC自动机明白了就会做了,不多说。。。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node{
int next[50*1010][128],fail[50*1010],vis[50*1010];
int sz,root;
int flag[1010];
int newnode() {
memset(next[sz],0,sizeof(next[sz]));
vis[sz++]=0;
return sz-1;
}
void init() {
sz=0;
root=newnode();
memset(flag,0,sizeof(flag));
}
void insert(char s[],int id) {
int i,te=root;
for(i=0; s[i]; i++) {
if(next[te][s[i]]==0) {
int p = newnode();
next[te][s[i]] = p;
te=p;
}
else te = next[te][s[i]];
}
vis[te] = id;
}
void build_ac_automation() {
fail[root] = root;
int i;
queue<int> que;
for(i=0; i<128; i++) {
if(next[root][i]==0) {
next[root][i] = root;
}
else {
fail[next[root][i]] = root;
que.push(next[root][i]);
}
}
while(!que.empty()) {
int te=que.front();
que.pop();
for(i=0; i<128; i++) {
if(next[te][i]==0) next[te][i] = next[fail[te]][i];
else {
fail[next[te][i]] = next[fail[te]][i];
que.push(next[te][i]);
}
}
}
}
void query(char s[]) {
int te=root,i;
for(i=0; s[i]; i++) {
te = next[te][s[i]];
int p = te;
while(p!=root) {
if(vis[p]) {
flag[vis[p]]++;
}
p = fail[p];
}
}
}
};
node ac;
char s[1005][100],str[2000010];
int main() {
int n,i;
while(scanf("%d",&n)!=EOF) {
//getchar();
ac.init();
for(i=1; i<=n; i++) {
scanf("%s",s[i]);
ac.insert(s[i],i);
}
ac.build_ac_automation();
scanf("%s",str);
//cout<<str<<endl;
ac.query(str);
//cout<<str<<endl;
for(i=1; i<=n; i++) {
if(ac.flag[i])
printf("%s: %d\n",s[i],ac.flag[i]);
}
}
return 0;
}