当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。
每个病毒都有一个编号,依此为1—N。
不同编号的病毒特征码不会相同。
在这之后一行,有一个整数M(1<=M<=1000),表示网站数。
接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。
每个网站都有一个编号,依此为1—M。
以上字符串中字符都是ASCII码可见字符(不包括回车)。
web 网站编号: 病毒编号 病毒编号 …
冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
最后一行输出统计信息,如下格式
total: 带病毒网站数
冒号后有一个空格。
3 aaa bbb ccc 2 aaabbbccc bbaacc
web 1: 1 2 3 total: 1
AC自动机模版题 输出病毒编号只要用个变量标记一下就好了。统计有哪几个病毒出现过用mark数组 就是检查有没有出现的时候检查到n即可,省时。
#include <iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=100010; char str[10010],keyword[201],mark[501]; int num,ccase; struct node { node *fail; node *next[95]; int count,pos; node() { fail=NULL; count =0; pos=0; for(int i=0;i<95;i++) { next[i]=NULL; } } }*q[maxn]; node *root; void insert(char *s) { int tmp,len; node *p=root; for(int i=0;s[i]!='\0';i++) { tmp=s[i]-33; //ASCII码可见字符设为95,减33 if(p->next[tmp]==NULL) p->next[tmp]=new node(); p=p->next[tmp]; } p->count++; p->pos=num++; //病毒编号 } void build_ac() { q[0]=root; root->fail=NULL; for(int move=0,save=1;move<save;move++) { node *now=q[move]; for(int i=0;i<95;i++) { if(now->next[i]) { node *p=now->fail; while(p&&!p->next[i])p=p->fail; now->next[i]->fail=p?p->next[i]:root; q[save++]=now->next[i]; } } } } int query() { node *now=root; int ans=0; int flag=0; for(int i=0;str[i];i++) { int index=str[i]-33; while(now&&!now->next[index])now=now->fail; now=now?now->next[index]:root; for(node *p=now;p!=NULL;p=p->fail) { if(p->count==1) { mark[p->pos]=1; flag=1; //cout<<p->pos<<endl; } } } return flag; } int main() { int n; while(~scanf("%d",&n)) { memset(q,0,sizeof(q)); root=new node(); getchar(); num=1; int tmp; tmp=n; while(n--) { gets(keyword); insert(keyword); } build_ac(); int m; scanf("%d",&m); ccase=1; int ans=0; while(m--) { scanf("%s",str); memset(mark,0,sizeof(mark)); int flag=query(); if(flag==1){ printf("web %d:",ccase); for(int i=1;i<=tmp;i++) if(mark[i])printf(" %d",i); ans++; printf("\n"); } ccase++; } printf("total: %d\n",ans); } return 0; }