zoukankan      html  css  js  c++  java
  • Hdu 3065 病毒侵袭持续中(AC自动机)

    病毒侵袭持续中
    Time Limit: 2000 Memory Limit: 32768
    Problem Description
    小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
    Input
    第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
    接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
    在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
    Output
    按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
    病毒特征码: 出现次数
    冒号后有一个空格,按病毒特征码的输入顺序进行输出。
    Sample Input
    3
    AA
    BB
    CC
    ooxxCC%dAAAoen….END
    Sample Output
    AA: 2
    CC: 1
    Hint
    Hit:
    题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。
    计数策略也可一定程度上从Sample中推测。
    Source
    2009 Multi-University Training Contest 16 - Host by NIT

    /*
    这题不是1A.
    吐槽一下:又是多组输入.
    有几个点需要注意一下.
    这题是不需要用mark判重的,这点没想到.
    还有出现不合法字符的时候要指针要指到root.
    不然就认为是忽略了不合法字符把两边连接起来了.
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define MAXN 50010
    #define MAXM 2000010
    using namespace std;
    int n,m,l,tot=1,a[1001],fail[MAXN];
    char s[MAXM],ch[1001][52];
    struct data{int x[27],b;}tree[MAXN];
    queue<int>q;
    void add(int t)
    {
        l=strlen(s+1);int now=1;
        for(int i=1;i<=l;i++)
        {
            int x=s[i]-64;
            if(!tree[now].x[x]) tree[now].x[x]=++tot;
            now=tree[now].x[x];
        }
        tree[now].b=t;
        return ;
    }
    void get_fail()
    {
        for(int i=1;i<=26;i++) tree[0].x[i]=1;
        q.push(1);
        while(!q.empty())
        {
            int now=q.front();q.pop();
            for(int i=1;i<=26;i++)
            {
                if(!tree[now].x[i]) continue;
                int k=fail[now];
                while(!tree[k].x[i]) k=fail[k];
                k=tree[k].x[i];
                fail[tree[now].x[i]]=k;
                q.push(tree[now].x[i]);
            }
        }
        return ;
    }
    void Mark()
    {
        int now=1;l=strlen(s+1);
        for(int i=1;i<=l;i++)
        {
            if(s[i]<'A'||s[i]>'Z') {now=1;continue;}
            int x=s[i]-64;
            while(!tree[now].x[x]) now=fail[now];
            now=tree[now].x[x];
            int k=now;
            while(k)
            {
                if(tree[k].b) a[tree[k].b]++;
                k=fail[k];
            }
        }
        return ;
    }
    void Clear()
    {
        memset(ch,0,sizeof ch);// 1 w.
        memset(fail,0,sizeof fail);
        memset(a,0,sizeof a);
        memset(tree,0,sizeof tree);
        tot=1;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            Clear();
            for(int i=1;i<=n;i++)
            {
                scanf("%s",s+1),add(i);
                for(int j=1;j<=strlen(s+1);j++) ch[i][j]=s[j];
            }
            get_fail();
            scanf("%s",s+1);
            Mark();
            for(int i=1;i<=n;i++)
              if(a[i]) printf("%s: %d
    ",ch[i]+1,a[i]);
        }
        return 0;
    }
  • 相关阅读:
    263邮箱配置告警发件配置
    交换机日期时间设置
    【Switch】- 配置日志文件输出syslog信息
    网络设备断电注意事项
    H3C交换机保存机制
    Docker学习笔记
    小型网络组网模型讲解
    Linux下管理员强行踢出用户的命令使用方法
    Linux SNMP 监控一些常用OID
    MySQL解决方案
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068035.html
Copyright © 2011-2022 走看看