病毒侵袭持续中 HDU - 3065 AC自动机
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 /*
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自动机的更多相关文章
- 病毒侵袭持续中 - HDU 3065(AC自动机,判断子串个数)
分析:依然是一个模板题,不过在写建立失败指针的地方竟然写错了三次....看来现在状态不太好. 代码如下: ============================================= ...
- AC日记——病毒侵袭持续中 hdu 3065
3065 思路: 好题: 代码: #include <queue> #include <cstdio> #include <cstring> using names ...
- 病毒侵袭持续中---hdu3065(AC自动机模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 模板题,没什么好说的... #include<stdio.h> #include&l ...
- HDU-3065 病毒侵袭持续中 字符串问题 AC自动机
题目链接:https://cn.vjudge.net/problem/HDU-3065 题意 跟上一道题是几乎一模一样,这次是统计关键词的出现次数 一个相当坑的地方,注意多组样例 思路 套模版 改in ...
- hdu 3065 病毒侵袭持续中【AC自动机】
<题目链接> 题目大意: 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的“万恶之源”.这是一个庞大的病毒网站,他有着好多好多的病毒,但是 ...
- HDU 3065 病毒侵袭持续中 (AC自动机)
题目链接 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒 ...
- HDU 3065 病毒侵袭持续中(AC自己主动机)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭 ...
- AC自动机---病毒侵袭持续中
HDU 3065 题目网址: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110773#problem/C Description 小t ...
- HDU 3065 病毒侵袭持续中
HDU 3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- python学习笔记 | 递归思想
1.引子 大师 L. Peter Deutsch 说过: To Iterate is Human, to Recurse, Divine. 中文译为:人理解迭代,神理解递归 2.什么是递归 简单理解: ...
- MySQL select 查询之分组和过滤
SELECT 语法 SELECT [ALL | DISTINCT] {* | table.* | [table.field1[as alias1][,table.field2[as alias2]][ ...
- 【排序基础】5、插入排序法 - Insertion Sort
插入排序法 - Insertion Sort 文章目录 插入排序法 - Insertion Sort 插入排序设计思想 插入排序代码实现 操作:插入排序与选择排序的比较 简单记录-bobo老师的玩转算 ...
- 使用sqluldr2进行oracle数据库抽取时执行后无反应,也无日志
使用sqluldr2进行oracle数据库表数据抽取时遇到执行后无反应,也不报错,也无日志输出的情况. 经过排查之后发现时由于oracle账户密码快要过期导致的(这也能出问题,我服,类似的plsql连 ...
- java锁的对象引用
当访问共享的可变数据时,通常需要同步.一种避免使用同步的方式就是不共享数据. 如果数据仅在单线程内访问,就不需要同步,这种技术称为"线程封闭",它是实现线程安全性最简单方式之一. ...
- Ubuntu16.04安装MySQL8.0
1.Ubuntu换源(阿里云) sudo cp /etc/apt/sources.list /etc/apt/sources.list.baksudo vi /etc/apt/sources.list ...
- 绝对定位上下左右都为0 margin为auto为什么能居中
老规矩,先来一段废话,我大学刚入门的时候觉得CSS很简单,记一记就会了,不就是盒模型嘛,现在想来觉得自己那时候真的很自以为是哈哈.但是随着工作沉淀,我明白了任何技术都有着它的深度和广度,正是因为不少人 ...
- 同步alv的前端显示和输出内表中的数据
在使用CL_GUI_ALV_GRID显示报表的时候,当我们使用了checkbox的时候,或者是有可编辑的字段,当我们 在前段修改了单元格内容的时候,后台的内表并不会自动的更新,此时需要我们调用一个方法 ...
- IP2723T中文规格书PDF
IP2723T 是一款集成多种协议.用于 USB 输出端口的快充协议 IC.支持多种快充协议,包括 USBTypeC DFP,PD2.0/PD3.0/PPS,HVDCPQC4/QC4+/QC3.0/Q ...
- (转载)微软数据挖掘算法:Microsoft 神经网络分析算法(10)
前言 有段时间没有进行我们的微软数据挖掘算法系列了,最近手头有点忙,鉴于上一篇的神经网络分析算法原理篇后,本篇将是一个实操篇,当然前面我们总结了其它的微软一系列算法,为了方便大家阅读,我特地整理了一篇 ...