zoukankan      html  css  js  c++  java
  • 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("
    ");
                total++;
            }
        }
        printf("total: %d
    ",total);
        return 0;
    }
  • 相关阅读:
    神经网络-FPN 19
    机器学习
    神经网络-DenseNet 18
    神经网路骨架:各自的特点统计
    转载:一步一步制作根文件系统
    设计模式博客
    【转】PowerPC平台linux设备移植
    【收藏】自己动手写编译器、连接器
    查看pthread线程库中锁的持有者方法
    【转】深入 Linux 的进程优先级
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676378.html
Copyright © 2011-2022 走看看