题目描述是中文的。。
http://acm.hdu.edu.cn/showproblem.php?pid=2896
样例太有迷惑性了。 没想到它存储的是128个字符信息。这跟平时所经常碰到的不太一样。。
还是题目没读清楚啊。。 然后又因为ASCII码是从 32开始时网站中会出现的。。所以从31开始计数。
http://www.cnblogs.com/songsu/articles/1454333.html ASCII 表
第二次做AC自动机的题目了。。路漫漫兮
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <vector>
#include <memory.h>
#include <algorithm>
using namespace std;
const int N = 500000;
struct node{
node *fail;
node *next[130];
int id;
void clear(){
fail=NULL;
id = -1;
memset(next,0,sizeof(next));
}
}stack[N], *root,*cur,*q[N];
int head,tail;
bool vis[11111];
char virus[11111],website[111111];
vector<int> ret;
void insert(char s[],int id){
node* p =root;
int n = strlen(s),o;
for(int i = 0;i < n;i++){
o = s[i]-31;
if(p->next[o]==NULL){
p->next[o]=++cur;
cur->clear();
}
p=p->next[o];
}
p->id = id;
}
void do_AC(){
node *p,*tmp;
head = tail = 0;
q[tail++]=root;
while(head!=tail){
p = q[head++];
for(int i = 0;i <= 128;i++){
if(p->next[i] != NULL){
q[tail++]=p->next[i];
if(p == root){
p->next[i]->fail = root;
}else{
tmp = p->fail;
while(tmp != NULL){
if(tmp->next[i]!=NULL){
p->next[i]->fail=tmp->next[i];
break;
}
tmp = tmp->fail;
}
if(tmp == NULL){
p->next[i]->fail=root;
}
}
}
}
}
}
void query(char s[]){
node *p=root,*tmp;
int n = strlen(s),o;
ret.clear();
for(int i=0;i < n;i++){
o = s[i]-31;
while(p->next[o]==NULL && p != root)
p = p->fail;
p = p->next[o];
if(p == NULL)
p = root;
tmp = p;
while(tmp != root && tmp->id!=-1){
if(!vis[tmp->id]){
vis[tmp->id]=true;
ret.push_back(tmp->id);
}
tmp=tmp->fail;
}
}
}
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF){
root = cur = stack;
cur->clear();
for(int i = 1;i <= n;i++){
scanf("%s",virus);
insert(virus,i);
}
scanf("%d",&m);
do_AC();
int total=0;
for(int i = 1;i <= m;i++){
scanf("%s",website);
memset(vis,0,sizeof(vis));
query(website);
if(ret.size() != 0){
total++;
sort(ret.begin(),ret.end());
printf("web %d:",i);
for(int j = 0;j < ret.size();j++)
printf(" %d",ret[j]);
printf("\n");
}
}
printf("total: %d\n",total);
}
return 0;
}