HDU2896 病毒侵袭 【AC自动机】

HDU2896 病毒侵袭


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


一开始体面上说是所有可见ASCLL字符我就蒙了,后来看网上说开到一百三就好,然后就开开心心的Presentation Error了,后来删掉一个没用的空格。。就AC了。。诶,不知道忽略行末空格吗。。。


思路挺简单的,就是对于每个串暴力跑一遍就好了。。。


#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define M 10010
struct Node{
    int fail,id,ch[130];
    void clean(){
        fail=id=0;
        memset(ch,0,sizeof(ch));
    }
}t[N];
char s[M];
bool vis[M];
int n,m,tot,cnt,total,ans[5];
void init(){
    tot=1;total=0;
    t[0].clean();t[1].clean();
    for(int i=0;i<130;i++)t[0].ch[i]=1;
}
void insert(char *s,int id){
    int len=strlen(s),u=1;
    for(int i=0;i<len;i++){
        int tmp=s[i];
        if(!t[u].ch[tmp])
            t[t[u].ch[tmp]=++tot].clean();
        u=t[u].ch[tmp];
    }
    t[u].id=id;
}
void buildFail(){
    queue<int> q;q.push(1);
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<130;i++){
            int w=t[u].ch[i],v=t[u].fail;
            while(!t[v].ch[i])v=t[v].fail;
            v=t[v].ch[i];
            if(w){
                t[w].fail=v;
                q.push(w);
            }else t[u].ch[i]=v;
        }
    }
} 
void collect(int u){
    while(u){
        if(t[u].id&&!vis[t[u].id]){
            vis[t[u].id]=1;
            ans[++cnt]=t[u].id;
        }
        u=t[u].fail;
    }
}
int main(){
    init();
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        insert(s,i);
    }
    buildFail();
    scanf("%d",&m);
    for(int k=1;k<=m;k++){
        memset(ans,0,sizeof(ans));
        memset(vis,0,sizeof(vis));
        scanf("%s",s);
        cnt=0;
        int len=strlen(s),u=1;
        for(int i=0;i<len;i++){
            int tmp=s[i];
            u=t[u].ch[tmp];
            collect(u);
        }
        if(ans[1]){
            sort(ans+1,ans+cnt+1);
            printf("web %d: ",k);
            for(int i=1;i<=cnt;i++){
                printf("%d",ans[i]);
                if(i!=cnt)printf(" ");//不这样写会Presentation Error
            }
            printf("\n");
            total++;
        }
    }
    printf("total: %d\n",total);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dream_maker_yk/article/details/80753249
今日推荐