Problem Description
当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
 
Input
第一行,一个整数N(1<=N<=500),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。
每个病毒都有一个编号,依此为1—N。
不同编号的病毒特征码不会相同。
在这之后一行,有一个整数M(1<=M<=1000),表示网站数。
接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。
每个网站都有一个编号,依此为1—M。
以上字符串中字符都是ASCII码可见字符(不包括回车)。
 
Output
依次按如下格式输出按网站编号从小到大输出,带病毒的网站编号和包含病毒编号,每行一个含毒网站信息。
web 网站编号: 病毒编号 病毒编号 …
冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
最后一行输出统计信息,如下格式
total: 带病毒网站数
冒号后有一个空格。
 
Sample Input
3
aaa
bbb
ccc
2
aaabbbccc
bbaacc
 
Sample Output
web 1: 1 2 3
total: 1
 
Source
 
Recommend
gaojie

AC自动机,好像有点懂了

建好存放病毒码的trie树,并升级成自动机,(end[]数组用来存放病毒的id),然后依次读入网站源码,读一个搜一个即可

 /**/
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
struct ACa{
int next[][],fail[],end[];
int root,len;
int newnode(){
for(int i=;i<;i++)
next[len][i]=-;
end[len]=-;
len++;
return len-;
}
void clear(){
len=;
root=newnode();
return;
}
void insert(char s[],int num){//建立trie树
int ls=strlen(s);
int now=root;
for(int i=;i<ls;i++){
if(next[now][s[i]]==-)
next[now][s[i]]=newnode();
now=next[now][s[i]];
}
end[now]=num;//存储病毒id
}
void build(){//建自动机
queue<int>q;
int i;
fail[root]=root;
for(i=;i<;i++){
if(next[root][i]==-)
next[root][i]=root;
else{
fail[next[root][i]]=root;
q.push(next[root][i]);
}
}
while(!q.empty()){
int now=q.front();
q.pop();
for(i=;i<;i++){
if(next[now][i]==-)
next[now][i]=next[fail[now]][i];
else{
fail[next[now][i]]=next[fail[now]][i];
q.push(next[now][i]);
}
}
}
return;
}
bool vis[];
bool ask(char c[],int n,int num){//源码 病毒数 网站编号
bool flag1=false;
memset(vis,false,sizeof(vis));
int lc=strlen(c);
int now=root;
int i;
for(i=;i<lc;i++){
now=next[now][c[i]];
int temp=now;
while(temp!=root){
if(end[temp]!=-){//找到病毒
flag1=;
vis[end[temp]]=;
}
temp=fail[temp];
}
}
if(!flag1)return false;
printf("web %d:",num);
for(i=;i<=n;i++) if(vis[i])printf(" %d",i);
printf("\n");
return true;
}
};
ACa ac;
char s[];
int n,m;
int main(){
int i,j;
while(scanf("%d",&n)!=EOF){
ac.clear();
for(i=;i<=n;i++) scanf("%s",s) , ac.insert(s,i);
ac.build();
scanf("%d",&m);
int ans=;
for(i=;i<=m;i++){
scanf("%s",s);
if(ac.ask(s,n,i))ans++;
}
printf("total: %d\n",ans);
}
return ;
}

HDU 2896 病毒侵袭的更多相关文章

  1. hdu 2896 病毒侵袭 ac自动机

    /* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...

  2. hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. HDU 2896 病毒侵袭 (AC自己主动机)

    pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...

  4. HDU 2896 病毒侵袭(AC自动机水)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. HDU 2896 病毒侵袭(AC自动机)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. hdu 2896 病毒侵袭 AC自动机 基础题

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  7. HDU 2896 病毒侵袭 AC自己主动机题解

    本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...

  8. HDU 2896 病毒侵袭【AC自动机】

    <题目链接> Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一 ...

  9. HDU 2896 病毒侵袭 【AC自动机】

    HDU 2222 仅仅求出了和文本串匹配的模式串个数,本题要求求出匹配的模式串的编号. 不同的部分在代码中的注释部分. #include <cstdio> #include <cst ...

随机推荐

  1. Android 下的EXIF

    一.什么是Exif Exif(Exchangeable Image File 可交换图像文件)是一种图象文件格式,它的数据存储与JPEG格式是完全相同的.实际上Exif格式就是在JPEG格式头部插入了 ...

  2. windows7下修改hosts文件无效解决办法

    通常会为了开发方便.或者屏蔽掉一些恶意网站,我们会在hosts(c:\windows\system32\drivers\etc\hosts)文件中进行相应的域名指向,例:

  3. 如何在Ubuntu 14.04中安装最新版Eclipse

    想必很多开发人员都知道,Ubuntu 软件源中提供的并不是最新版本的 Eclipse,本教程就教大家如何在 Ubuntu 14.04 中快速安装 Eclipse 官方发布的最新版本. 到目前为止,Ec ...

  4. Java中sleep()和wait()的区别

    1. 这两个方法来自不同的类,sleep方法属于Thread,wait方法属于Object. 2. 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法. ...

  5. [CareerCup] 2.6 Linked List Cycle 单链表中的环

    2.6 Given a circular linked list, implement an algorithm which returns the node at the beginning of ...

  6. [CareerCup] 4.7 Lowest Common Ancestor of a Binary Search Tree 二叉树的最小共同父节点

    4.7 Design an algorithm and write code to find the first common ancestor of two nodes in a binary tr ...

  7. [CareerCup] 14.2 Try-catch-finally Java中的异常处理

    14.2 In Java, does the finally block get executed if we insert a return statement inside the try blo ...

  8. LeetCode:Jump Game I II

    Jump Game Given an array of non-negative integers, you are initially positioned at the first index o ...

  9. windows命令行

    [drive:] Change the current driver, without changing its current directory cd [drive:] [path] Just c ...

  10. 表单验证之validform.js使用方法

    一.validform有什么用? 网页上有大量的input需要你进行验证的时候,如果是弹窗的话,需要不停地判断,如果为空,弹窗.如果不是数字,弹窗. 所以要将这么多验证交给一个js去验证. 二.我现在 ...