• hdu 3065 病毒侵袭持续中 AC自动机


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065

    小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
    Input
    第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
    接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
    在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
    Output
    按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
    病毒特征码: 出现次数
    冒号后有一个空格,按病毒特征码的输入顺序进行输出。
     
    题意描述:中文题,如上所述。
    算法分析:AC自动机的简单题,大白书和很多博客都有AC自动机的详细介绍。AC自动机真心是个字符串处理的神奇东西,好好学习一下。
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<algorithm>
      7 #define inf 0x7fffffff
      8 #define PI 3.141592654
      9 #define exp 1e-10
     10 using namespace std;
     11 const int maxn=1000+10;
     12 const int M = 2000000+10;
     13 
     14 struct node
     15 {
     16     node *fail;
     17     node *child[26];
     18     int count;
     19     int id;
     20     node () {
     21         fail=NULL;
     22         count=0;
     23         id=-1;
     24         memset(child,NULL,sizeof(child));
     25     }
     26 }*q[50000+100];
     27 int head,tail;
     28 int n;
     29 char keyword[maxn][55];
     30 int an[maxn];
     31 char str[M];
     32 
     33 void insert(node *root,char *str,int k)
     34 {
     35     node *p=root;
     36     int len=strlen(str);
     37     for (int i=0 ;i<len ;i++)
     38     {
     39         int index=str[i]-'A';
     40         if (p->child[index]==NULL) p->child[index]=new node();
     41         p=p->child[index];
     42     }
     43     p->count++;
     44     p->id=k;// no repeat
     45     return ;
     46 }
     47 void build_AC(node *root)
     48 {
     49     root->fail=NULL;
     50     q[head++]=root;
     51     while (head != tail)
     52     {
     53         node *temp=q[tail++];
     54         node *p=NULL;
     55         for (int i=0 ;i<26 ;i++)
     56         {
     57             if (temp->child[i]!=NULL)
     58             {
     59                 if (temp==root) temp->child[i]->fail=root;
     60                 else
     61                 {
     62                     p=temp->fail;
     63                     while (p!=NULL)
     64                     {
     65                         if (p->child[i]!=NULL)
     66                         {
     67                             temp->child[i]->fail=p->child[i];
     68                             break;
     69                         }
     70                         p=p->fail;
     71                     }
     72                     if (p==NULL) temp->child[i]->fail=root;
     73                 }
     74                 q[head++]=temp->child[i];
     75             }
     76         }
     77     }
     78     return ;
     79 }
     80 void find(node *root,char *str)
     81 {
     82     int len=strlen(str);
     83     node *p=root;
     84     for (int i=0 ;i<len ;i++)
     85     {
     86         if (str[i]>='A' && str[i]<='Z')
     87         {
     88             int index=str[i]-'A';
     89             while (p->child[index]==NULL && p!=root) p=p->fail;
     90             p=p->child[index];
     91             p= p==NULL ? root : p ;
     92             node *temp=p;
     93             while (temp!=root)
     94             {
     95                 if (temp->count) an[temp->id ]++;
     96                 temp=temp->fail;
     97             }
     98         }
     99         else p=root;
    100     }
    101     return ;
    102 }
    103 int main()
    104 {
    105     while (scanf("%d",&n)!=EOF)
    106     {
    107         head=tail=0;
    108         memset(str,0,sizeof(str));
    109         memset(keyword,0,sizeof(keyword));
    110         memset(an,0,sizeof(an));
    111         node *root=new node();
    112 
    113         for (int i=0 ;i<n ;i++)
    114         {
    115             scanf("%s",keyword[i]);
    116             insert(root,keyword[i],i);
    117         }
    118         build_AC(root);
    119         getchar() ;gets(str) ;
    120         find(root,str);
    121         for (int i=0 ;i<n ;i++)
    122         if (an[i]) printf("%s: %d
    ",keyword[i],an[i]);
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    RegularExpressions(正则表达式)
    IntelliJ Idea工具使用
    JavaScript总结
    Ajax技术基础
    配置Nginx作为反向代理服务器
    SpringBoot下的Dubbo和Zookeeper整合
    springSecurity初识练气初期
    Spring Security拦截器加载流程分析练气中期
    Spring Security认证流程分析练气后期
    springBoot整合spring security+JWT实现单点登录与权限管理前后端分离筑基中期
  • 原文地址:https://www.cnblogs.com/huangxf/p/4379182.html
Copyright © 2020-2023  润新知