小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中推测。

题解:

病毒侵袭 HDU - 2896差不多

注意:

1:gets读入
2:由于目标串中匹配的时候有很多字符,但是你又不能去掉他们,但是next数组开到127的话太消耗内存,我的做法除了 'A'-'Z' 的字符之外的所有字母都变成 'Z'+1 ,这样的话只要开 next[27] 就够了。
 
  1 /*
2 代码中:
3 叶节点:代表此节点下没有子节点
4 根节点:就是树的根
5 子节点:就是这个节点的直接相连的节点(直系节点)
6
7 此代码:
8 用题目所给模式串构成一颗字典树
9 然后找出来给出的待求串中每种模式串出现
10
11 */
12 #include<stdio.h>
13 #include<iostream>
14 #include<string.h>
15 #include<algorithm>
16 #include<queue>
17 using namespace std;
18 const int maxn=5e4+10;
19 const int N=28;
20 typedef long long ll;
21 int v[1005];
22 char ss[1005][55];
23 struct Trie
24 {
25 int next[maxn][N],fail[maxn],ends[maxn];
26 int root,L;
27 int New_node() //创建一个新节点
28 {
29 for(int i=0; i<N; ++i)
30 {
31 next[L][i]=-1;
32 }
33 ends[L++]=0;
34 return L-1;
35 }
36 void init() //创建根节点
37 {
38 L=0;
39 root=New_node();
40 }
41 void inserts(char s[],int x) //往字典树里面插入新字符串
42 {
43 int len=strlen(s);
44 int now=root;
45 for(int i=0; i<len; ++i)
46 {
47 if(next[now][s[i]-'A']==-1)
48 next[now][s[i]-'A']=New_node();
49 now=next[now][s[i]-'A'];
50 }
51 ends[now]=x;
52 }
53 void build()
54 {
55 queue<int>r;
56 fail[root]=root;
57 for(int i=0; i<N; ++i)
58 {
59 if(next[root][i]==-1)
60 {
61 next[root][i]=root;
62 }
63 else
64 {
65 fail[next[root][i]]=root;
66 r.push(next[root][i]);
67 }
68 }
69 while(!r.empty())
70 {
71 int now=r.front();
72 r.pop();
73 for(int i=0; i<N; ++i)
74 {
75 if(next[now][i]==-1)
76 {
77 next[now][i]=next[fail[now]][i]; //叶节点处没有设置失败节点而是往next上接了一段,这个时候
78 //这个fail里面的值已经在下面的else里面放过东西了
79 }
80 else
81 {
82 fail[next[now][i]]=next[fail[now]][i]; //此节点的子节点的失败节点就是此节点失败节点对应字符位置
83 r.push(next[now][i]);
84 }
85 }
86 }
87 }
88 void query(char s[])
89 {
90 int len=strlen(s);
91 int now=root;
92 //int res=0;
93 for(int i=0; i<len; ++i)
94 {
95 now=next[now][s[i]-'A']; //这个now就保证了我们找的肯定是这个字符串中的一部分
96 int temp=now; //这就是一直找,找到了就加1,找不到就通过失败节点看其他地方能不能找到
97 while(temp!=root)
98 {
99 if(ends[temp])
100 {
101 v[ends[temp]]++;
102 }
103 //res+=ends[temp];
104 //ends[temp]=0;
105 temp=fail[temp];
106 }
107 }
108 //return res;
109 }
110 };
111 char s[2000010];
112 Trie ac;
113 int main()
114 {
115 // int t;
116 // scanf("%d",&t);
117 // while(t--)
118 // {
119 int n;
120 while(~scanf("%d",&n))
121 {
122 memset(v,0,sizeof(v));
123 ac.init();
124 for(int j=1; j<=n; ++j)
125 {
126 scanf("%s",ss[j]);
127 int len=strlen(ss[j]);
128 for(int i=0; i<len; ++i)
129 {
130 if(ss[j][i]>'Z' || ss[j][i]<'A')
131 {
132 ss[j][i]='A'+27;
133 }
134 }
135 ac.inserts(ss[j],j);
136 }
137 getchar();
138 ac.build();
139 gets(s);
140 int len=strlen(s);
141 for(int i=0; i<len; ++i)
142 {
143 if(s[i]>'Z' || s[i]<'A')
144 {
145 s[i]='A'+27;
146 }
147 }
148 //printf("**\n");
149 ac.query(s);
150 //printf("*");
151 for(int i=1; i<=n; ++i)
152 {
153 if(v[i])
154 {
155 printf("%s: %d\n",ss[i],v[i]);
156 }
157 }
158 }
159
160 // }
161 return 0;
162 }

病毒侵袭持续中 HDU - 3065 AC自动机的更多相关文章

  1. 病毒侵袭持续中 - HDU 3065(AC自动机,判断子串个数)

    分析:依然是一个模板题,不过在写建立失败指针的地方竟然写错了三次....看来现在状态不太好.   代码如下: ============================================= ...

  2. AC日记——病毒侵袭持续中 hdu 3065

    3065 思路: 好题: 代码: #include <queue> #include <cstdio> #include <cstring> using names ...

  3. 病毒侵袭持续中---hdu3065(AC自动机模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 模板题,没什么好说的... #include<stdio.h> #include&l ...

  4. HDU-3065 病毒侵袭持续中 字符串问题 AC自动机

    题目链接:https://cn.vjudge.net/problem/HDU-3065 题意 跟上一道题是几乎一模一样,这次是统计关键词的出现次数 一个相当坑的地方,注意多组样例 思路 套模版 改in ...

  5. hdu 3065 病毒侵袭持续中【AC自动机】

    <题目链接> 题目大意: 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的“万恶之源”.这是一个庞大的病毒网站,他有着好多好多的病毒,但是 ...

  6. HDU 3065 病毒侵袭持续中 (AC自动机)

    题目链接 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒 ...

  7. HDU 3065 病毒侵袭持续中(AC自己主动机)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭 ...

  8. AC自动机---病毒侵袭持续中

    HDU 3065 题目网址: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110773#problem/C Description 小t ...

  9. HDU 3065 病毒侵袭持续中

    HDU 3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

随机推荐

  1. mybatis入门教程之搭建一个简单的mybatis项目并启动它

    一.准备条件: 1.依赖jar包:mybatis核心包(必须).lombok插件包(非必须)以及MySQL数据库连接驱动包(必须) <dependency> <groupId> ...

  2. 【Oracle】10g 11g下载路径

    现在直接点击不能下载了 要经过oracle许可才可以下载 如果嫌麻烦可以用迅雷直接下载密码是这个 一般不会动了 大家也不用帮我找回密码了 每次都改 也很麻烦的用迅雷下就不用密码了 下载也不会卡到最后 ...

  3. cmd的终结工具cmder

    常用快捷键 win+alt+t  打开任务设置窗口 win+alt+k 打开快捷键设置窗口 自定义屏幕分割窗口快捷键: ctl+shift+s 水平按50%比例分割 ctl+shift+v 垂直按50 ...

  4. 二本学生拿到腾讯大厂offer的成长记录

    本人迈莫,是在20年以春招实习生的身份进入鹅厂,经过重重波折,最终成为鹅仔一份子.接下来我会以我亲生经历为例,分享一下普通大学的学生也是可以进去大厂,拭目以待!!! 初入大学 惨遭毒打 时间倒回到17 ...

  5. 从零开始学spring源码之xml解析(一):入门

    谈到spring,首先想到的肯定是ioc,DI依赖注入,aop,但是其实很多人只是知道这些是spring核心概念,甚至不知道这些代表了什么意思,,作为一个java程序员,怎么能说自己对号称改变了jav ...

  6. MySQL中 utf8与utf8mb4的区别

    MySQL中 utf8与utf8mb4的区别 一.简介 ​ MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode.好在 ...

  7. Bitter.Core系列十:Bitter ORM NETCORE ORM 全网最粗暴简单易用高性能的 NETCore 之 Log 日志

    Bitter 框架的 Log 全部采用 NLog 日志组件.Bitter.Core 的 执行语句的日志记录 Nlog 日志级别为:info.  如果想要查看Bitter.Core 的执行SQL,先要去 ...

  8. 使用eventfd创建一个用于事件通知的文件描述符

    https://www.jianshu.com/p/57cc1d7d354f nat穿透代码c++

  9. 为什么要使用 do while(0)?

    两点 避免宏定义的花括号对代码的完整性造成影响 可以在指定的代码块中(do{})使用break提前跳出,避免goto.

  10. css水平、垂直居中的写法

    水平居中 行内元素: text-align: center 块级元素: margin: 0 auto position:absolute +left:50%+ transform:translateX ...