• 数据结构--AC自动机--hdu 2896


    病毒侵袭

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 9363    Accepted Submission(s): 2444

    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




    AC自动机模板题。。。。。。
    tips:
           ASCII码的不可见字符,他们是0~31,以及127。
    代码:
      1 #include "queue"  //hdu 2896
      2 #include "cstdio"
      3 #include "cstring"
      4 #include "algorithm"
      5 using namespace std;
      6 
      7 int a[1005][4];  //a[i][]记录第i个网站所包含的病毒编号
      8 bool flag[505];
      9 
     10 struct node
     11 {
     12     int count;
     13     node *fail;
     14     node *next[95];  //ASCII码可见字符为32~126,共95个;
     15     node()
     16     {
     17         count = 0;
     18         fail = NULL;
     19         memset(next,NULL,sizeof(next));
     20     }
     21 };
     22 
     23 void Insert(node *root,char *s,int k)
     24 {
     25     node *p = root;
     26     int i,index;
     27     for(i=0; s[i]!=''; ++i)
     28     {
     29         index = s[i]-32;
     30         if(p->next[index]==NULL)
     31             p->next[index] = new node();
     32         p = p->next[index];
     33     }
     34     p->count = k;
     35 }
     36 
     37 void Build_ac_automation(node *root)  //建立失败指针
     38 {
     39     int i;
     40     root->fail = NULL;
     41     node *p,*temp;
     42     queue<node *> q;
     43     q.push(root);
     44     while(!q.empty())   //bfs构造失败指针
     45     {
     46         temp = q.front();
     47         q.pop();
     48         p = NULL;
     49         for(i=0; i<95; ++i)
     50         {
     51             if(temp->next[i]==NULL) continue;
     52             if(temp==root)
     53             {
     54                 temp->next[i]->fail = root;
     55                 q.push(temp->next[i]);
     56                 continue;
     57             }
     58             p = temp->fail;
     59             while(p!=NULL)
     60             {
     61                 if(p->next[i]!=NULL){
     62                     temp->next[i]->fail = p->next[i];
     63                     break;
     64                 }
     65                 p = p->fail;
     66             }
     67             if(p==NULL)
     68                 temp->next[i]->fail = root;
     69             q.push(temp->next[i]);
     70         }
     71     }
     72 }
     73 
     74 void Query(node *root,char *s,int *a)
     75 {
     76     int k = 1;
     77     int i,index;
     78     node *p = root;
     79     memset(flag,false,sizeof(flag));
     80     for(i=0; s[i]!=''; ++i)
     81     {
     82         index = s[i]-32;
     83         while(p->next[index]==NULL && p!=root)
     84             p = p->fail;
     85         p = p->next[index];
     86         p = (p==NULL) ? root:p;
     87         node *temp = p;
     88         while(temp!=root && flag[temp->count]!=true)
     89         {
     90             if(temp->count!=0){
     91                 a[k++] = temp->count;
     92                 flag[temp->count] = true;
     93             }
     94             temp = temp->fail;
     95         }
     96     }
     97     a[0] = k-1;
     98 }
     99 
    100 void BFS(node *p)
    101 {
    102     int i;
    103     for(i=0; i<95; ++i)
    104     {
    105         if(p->next[i]!=NULL)
    106             BFS(p->next[i]);
    107     }
    108     delete p;
    109 }
    110 
    111 int main()
    112 {
    113     int i;
    114     int n;
    115     char s[205];
    116     char str[10010];
    117     while(scanf("%d",&n)!=-1)
    118     {
    119         node *root = new node();
    120         getchar();
    121         for(i=1 ;i<=n; ++i)
    122         {
    123             scanf("%s",s);
    124             Insert(root,s,i);
    125         }
    126         Build_ac_automation(root);
    127         int m;
    128         scanf("%d",&m);
    129         getchar();
    130         memset(a,0,sizeof(a));
    131         for(i=1; i<=m; ++i)
    132         {
    133             scanf("%s",str);
    134             Query(root,str,a[i]);
    135         }
    136         int ans = 0;
    137         for(i=1; i<=m; ++i)
    138         {
    139             if(a[i][0]!=0)
    140             {
    141                 ans++;
    142                 printf("web %d:",i);
    143                 sort(a[i]+1,a[i]+4);
    144                 for(int k=4-a[i][0]; k<=3; ++k)
    145                     printf(" %d",a[i][k]);
    146                 printf("
    ");
    147             }
    148         }
    149         BFS(root);
    150         printf("total: %d
    ",ans);
    151     }
    152     return 0;
    153 }


  • 相关阅读:
    qt调用simsimi api实现小黄鸡
    [机器学习系列] k-近邻算法(K–nearest neighbors)
    Ubuntu上安装flashplayer
    关于ubuntu下qt编译显示Cannot connect creator comm socket /tmp/qt_temp.xxx/stub-socket的解决办法
    Linux下添加源的几种方法
    Ubuntu字符界面输入密码始终提示错误 login incorrect 解决办法
    boost::algorithm(字符串算法库)
    boost::assign(标准容器填充库)
    boost::format(字符串格式化库)
    C/C++内存对齐 ZZ
  • 原文地址:https://www.cnblogs.com/ruo-yu/p/4411984.html
Copyright © 2020-2023  润新知