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

    描述

    传送门:我是传送门

    小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?

    输入

    第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
    接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
    在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

    输出

    按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
    病毒特征码: 出现次数
    冒号后有一个空格,按病毒特征码的输入顺序进行输出。

    样例

    输入

    3
    AA
    BB
    CC
    ooxxCC%dAAAoen….END

    输出

    AA: 2
    CC: 1

    Note

    题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。
    计数策略也可一定程度上从Sample中推测。

    思路

    病毒侵袭实际上差不太多,也不知道我当时为什么写完病毒侵袭之后看了看这道题就放弃了。

    一开始很奇怪的RE了无数次,也不知道哪里写搓了,正在要绝望的时候突然AC了···

    代码

      1 /*
      2  * ==============================================
      3  *
      4  *       Filename:  C.cpp
      5  *
      6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=3065
      7  *
      8  *        Version:  1.0
      9  *        Created:  2018/09/26 23时12分29秒
     10  *       Revision:  none
     11  *       Compiler:  g++
     12  *
     13  *         Author:  杜宁元 (https://duny31030.top/), duny31030@126.com
     14  *   Organization:  QLU_浪在ACM
     15  *
     16  * ==============================================
     17  */
     18 #include <bits/stdc++.h>
     19 using namespace std;
     20 #define clr(a, x) memset(a, x, sizeof(a))
     21 #define rep(i,a,n) for(int i=a;i<=n;i++)
     22 #define pre(i,a,n) for(int i=n;i>=a;i--)
     23 #define ll long long
     24 #define max3(a,b,c) fmax(a,fmax(b,c))
     25 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     26 const double eps = 1e-6;
     27 const int INF = 0x3f3f3f3f;
     28 const int mod = 1e9 + 7;
     29 const int N = 1005;
     30 const int NN = 2001000;
     31 char m[NN];
     32 char vir[N][55];
     33 int a[N];
     34 struct node
     35 {
     36     int son[27];
     37     int fail;
     38     int count;
     39     int number;
     40 }ac[100*N];
     41 int tot = 0;
     42 void init()
     43 {
     44     clr(a,0);
     45     for(int i = 0;i < 50000;i++)
     46     {
     47         memset(ac[i].son,0,sizeof ac[i].son);
     48         ac[i].count = 0;
     49         ac[i].fail = 0;
     50         ac[i].number = 0;
     51     }
     52 }
     53 
     54 void Insert(char *s,int num)
     55 {
     56     int len = strlen(s);
     57     int now = 0;
     58     int tmp;
     59     for(int i = 0;i < len;i++)
     60     {
     61         tmp = s[i]-'A';
     62         if(ac[now].son[tmp] == 0)
     63             ac[now].son[tmp] = ++tot;
     64         now = ac[now].son[tmp];
     65     }
     66     ac[now].count++;
     67     ac[now].number = num;
     68 }
     69 
     70 void Insert1(char *s,int id)
     71 {
     72     int len = strlen(s);
     73     int now = 0;
     74     int tmp;
     75     for(int i = 0;i < len;i++)
     76     {
     77         tmp = s[i]-'A';
     78         if(ac[now].son[tmp] == 0)
     79             ac[now].son[tmp] = ++tot;
     80         now = ac[now].son[tmp];
     81     }
     82     ac[now].count++;
     83     ac[now].number = id;
     84 }
     85 
     86 void MakeFail()
     87 {
     88     queue<int> q;
     89     for(int i = 0;i < 26;i++)
     90     {
     91         if(ac[0].son[i] != 0)
     92         {
     93             ac[ac[0].son[i]].fail = 0;
     94             q.push(ac[0].son[i]);
     95         }
     96     }
     97     while(!q.empty())
     98     {
     99         int u = q.front();
    100         q.pop();
    101         for(int i = 0;i < 26;i++)
    102         {
    103             if(ac[u].son[i] != 0)
    104             {
    105                 ac[ac[u].son[i]].fail = ac[ac[u].fail].son[i];
    106                 q.push(ac[u].son[i]);
    107             }
    108             else 
    109                 ac[u].son[i] = ac[ac[u].fail].son[i];
    110         }
    111     }
    112 }
    113 
    114 void query(char *s)
    115 {
    116     int len = strlen(s);
    117     int now = 0,tmp;
    118     for(int i = 0;i < len;i++)
    119     {
    120         tmp = s[i]-'A';
    121         if(tmp < 0 || tmp > 25)
    122             tmp = 26;
    123         now = ac[now].son[tmp];
    124         for(int t = now;t && ac[t].count != -1;t = ac[t].fail)
    125         {
    126             if(ac[t].number > 0)
    127             {
    128                 a[ac[t].number]++;
    129             }
    130             // ans += ac[t].count;
    131             // ac[t].count = -1;
    132         }
    133     }
    134     // return ans;
    135 }
    136 
    137 int main()
    138 {
    139     ios
    140 #ifdef ONLINE_JUDGE 
    141 #else 
    142         freopen("in.txt","r",stdin);
    143     // freopen("out.txt","w",stdout); 
    144 #endif
    145     int n;
    146     while(scanf("%d",&n) != EOF)
    147     {
    148         init();
    149         rep(i,1,n)
    150         {
    151             scanf("%s",vir[i]);
    152             Insert1(vir[i],i);
    153         }
    154         ac[0].fail = 0;
    155         MakeFail();
    156         scanf("%s",m);
    157         query(m);
    158         rep(i,1,n)
    159         {
    160             if(a[i])
    161                 printf("%s: %d
    ",vir[i],a[i]);
    162         }
    163     }
    164     fclose(stdin);
    165     // fclose(stdout);
    166     return 0;
    167 }
  • 相关阅读:
    2020-2021:时间戳
    全链路压测落地和演进之路
    Socket粘包问题的3种解决方案,最后一种最完美!
    MySQL为Null会导致5个问题,个个致命!
    Maven中pom.xml的packaging类型
    mysql 二进制数据查询
    编写 Dockerfile 生成自定义镜像
    Python自动提取生成博客园年度报告
    [C#] 使用 Excel 和 Math.Net 进行曲线拟合和数据预测
    干货!亲子教育的6个阶段,不妨对照看看,你正处在哪一个阶段?
  • 原文地址:https://www.cnblogs.com/duny31030/p/14305082.html
Copyright © 2011-2022 走看看