链接:点击打开链接
题意:给出N个病毒的字符串,再给出M个网站的字符串,求字符串中含有病毒的数量和一共含有病毒的网址,具体看样例
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <queue>
using namespace std;
int str[100005][128],dis[100005];
int fail[100005],vis[100005];
int root,id;
void insert(char *s){
int u=0;
for(;*s;s++){
if(!str[u][*s-' '])
str[u][*s-' ']=root++;
u=str[u][*s-' '];
}
dis[u]=id++;
}
void getfail(){
int u,v,i,temp;
queue<int>q;
while(!q.empty())q.pop();
q.push(0);
while(q.size()){
u=q.front();q.pop();
for(i=0;i<128;i++)
if(v=str[u][i]){
if(u==0)
fail[v]=0;
else{
temp=fail[u];
while(temp&&!str[temp][i])
temp=fail[temp];
fail[v]=str[temp][i];
}
q.push(v);
}
}
}
int acauto(char *s){
int temp,star,sign;
temp=sign=0;
for(;*s;s++){
while(temp&&!str[temp][*s-' '])
temp=fail[temp];
star=temp=str[temp][*s-' '];
while(star&&!vis[star]&&dis[star]){
vis[star]=1;
star=fail[star];
sign=1;
}
}
if(sign)
return 1;
return 0;
} //这题就是AC自动机模板,唯一不同就是用一个vis数组记录
int main(){ //AC自动机模板和解析详见http://blog.csdn.net/stay_accept/article/details/47613961
int n,m,i,j,sum,flag;
char s[250],str[10005];
memset(str,0,sizeof(str));
memset(fail,0,sizeof(fail));
memset(dis,0,sizeof(dis));
root=id=1;sum=0;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%s",s);
insert(s);
}
getfail();
scanf("%d",&m);
for(i=1;i<=m;i++){
scanf("%s",str);
memset(vis,0,sizeof(vis));
if(acauto(str)){
printf("web %d:",i);
sum++;
for(j=0;j<root;j++){
flag=0;
if(vis[j]){
printf(" %d",dis[j]);
flag++;
}
if(flag==3)
break;
}
printf("\n");
}
}
printf("total: %d\n",sum);
return 0;
}