病毒侵袭 HDU - 2896 板子题
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小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
题解:
就跑一遍AC自动机代码就完了,比起原板子题Keywords Search HDU - 2222就改了一点
AC自动机代码详解看Keywords Search HDU - 2222
代码:
1 /*
2 代码中:
3 叶节点:代表此节点下没有子节点
4 根节点:就是树的根
5 子节点:就是这个节点的直接相连的节点(直系节点)
6
7 此代码:
8 用题目所给模式串构成一颗字典树
9 然后找出来给出的待求串中每种模式串出现几次
10
11
12 1.题目中的字符是除去回车的ASCII码可见字符(95个),我最开始定义的是以全部的ASCII码的个数(128)为基准的
13 2.输出要排序后再输出
14 */
15 #include<stdio.h>
16 #include<iostream>
17 #include<string.h>
18 #include<algorithm>
19 #include<queue>
20 using namespace std;
21 const int maxn=30000000;
22 typedef long long ll;
23 int visit[maxn],length[1005];
24 int v[1005][1005],n,m;
25 struct Trie
26 {
27 int next[maxn/100][128],fail[maxn],ends[maxn];
28 int root,L;
29 int New_node() //创建一个新节点
30 {
31 for(int i=0; i<128; ++i)
32 {
33 next[L][i]=-1;
34 }
35 ends[L++]=0;
36 return L-1;
37 }
38 void init() //创建根节点
39 {
40 L=0;
41 root=New_node();
42 }
43 void inserts(char s[],int x) //往字典树里面插入新字符串
44 {
45 int len=strlen(s);
46 int now=root;
47 for(int i=0; i<len; ++i)
48 {
49 if(next[now][s[i]]==-1)
50 next[now][s[i]]=New_node();
51 now=next[now][s[i]];
52 }
53 ends[now]=x;
54 }
55 void build()
56 {
57 queue<int>r;
58 fail[root]=root;
59 for(int i=0; i<128; ++i)
60 {
61 if(next[root][i]==-1)
62 {
63 next[root][i]=root;
64 }
65 else
66 {
67 fail[next[root][i]]=root;
68 r.push(next[root][i]);
69 }
70 }
71 while(!r.empty())
72 {
73 int now=r.front();
74 r.pop();
75 for(int i=0; i<128; ++i)
76 {
77 if(next[now][i]==-1)
78 {
79 next[now][i]=next[fail[now]][i]; //叶节点处没有设置失败节点而是往next上接了一段,这个时候
80 //这个fail里面的值已经在下面的else里面放过东西了
81 }
82 else
83 {
84 fail[next[now][i]]=next[fail[now]][i]; //此节点的子节点的失败节点就是此节点失败节点对应字符位置
85 r.push(next[now][i]);
86 }
87 }
88 }
89 }
90 void query(char s[],int x)
91 {
92 int len=strlen(s);
93 int now=root;
94 for(int i=0; i<len; ++i)
95 {
96 now=next[now][s[i]]; //这个now就保证了我们找的肯定是这个字符串中的一部分
97 int temp=now; //这就是一直找,找到了就加1,找不到就通过失败节点看其他地方能不能找到
98 while(temp!=root)
99 {
100 if(ends[temp] && !visit[temp])
101 {
102 visit[temp]=1;
103 v[x][length[x]++]=ends[temp];
104 }
105 temp=fail[temp];
106 }
107 }
108 }
109 };
110 char s[maxn];
111 Trie ac;
112 void init()
113 {
114 for(int i=0; i<=ac.L; ++i)
115 {
116 visit[i]=0;
117 }
118 for(int i=1; i<=n; ++i)
119 length[i]=0;
120 }
121
122 int main()
123 {
124 scanf("%d",&n);
125 ac.init();
126 for(int i=1; i<=n; ++i)
127 {
128 scanf("%s",s);
129 ac.inserts(s,i);
130 }
131 scanf("%d",&m);
132 ac.build();
133 int ans=0;
134 for(int i=1; i<=m; ++i)
135 {
136 init();
137 scanf("%s",s);
138 ac.query(s,i);
139 if(length[i])
140 {
141 ans++;
142 printf("web %d: ",i);
143 sort(v[i],v[i]+length[i]); //之前是忘记加这个一直错,想的时候还知道要排序,写代码的时候就忘了
144 for(int j=0; j<length[i]; ++j)
145 {
146 if(j!=length[i]-1) printf("%d ",v[i][j]);
147 else printf("%d\n",v[i][j]);
148 }
149 }
150 }
151 printf("total: %d\n",ans);
152 return 0;
153 }
病毒侵袭 HDU - 2896 板子题的更多相关文章
- 病毒侵袭 HDU - 2896(ac自动机 板题)
当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~ 但网路上总有那么些网站,开 ...
- 病毒侵袭 - HDU 2896(AC自动机)
分析:有点需要注意的,输入的字符是所有可见的ASCII码,刚开始没看清一直以为是小写字母.............注意到这点后这题就是裸的自动机了. 代码如下: ================= ...
- AC日记——病毒侵袭 hdu 2896
2896 思路: 好题: 代码: #include <queue> #include <cstdio> #include <cstring> using names ...
- hdu 2896 病毒侵袭 AC自动机 基础题
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- hdu2896 病毒侵袭 AC自动机入门题 N(N <= 500)个长度不大于200的模式串(保证所有的模式串都不相同), M(M <= 1000)个长度不大于10000的待匹配串,问待匹配串中有哪几个模式串,
/** 题目:hdu2896 病毒侵袭 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896 题意:N(N <= 500)个长度不大于200的模式串 ...
- HDu-2896 病毒侵袭,AC自动机模板题!
病毒侵袭 模板题,不多说了.. 题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数.格式请看 ...
- 敌兵布阵 HDU - 1166 板子题
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> ...
- HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)
最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...
- 病毒侵袭持续中 HDU - 3065 AC自动机
小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒 ...
随机推荐
- 记一道C语言编程题(C语言学习笔记)
题目如下 解答如下 #include <stdio.h> #include<math.h> double Mysqrt(double n) { return sqrt(n); ...
- oracle常用hint添加
1.视图添加索引 /* Formatted on 2020/1/6 下午 04:46:37 (QP5 v5.163.1008.3004) */ SELECT /*+index(VIEW_NAME.TA ...
- oracle ORA-00060死锁查询、表空间扩容
--查看被锁住的表 select b.owner,b.object_name,a.session_id,a.locked_mode from v$locked_object a,dba_objects ...
- [Usaco2016 Dec]Moocast
原题链接https://www.lydsy.com/JudgeOnline/problem.php?id=4749 可以对于每个点\(i\),往跟\(i\)距离小于等于\(p[i]\)的点\(j\)都 ...
- EFCore 5 新特性 —— Savepoints
EFCore 5 中的 Savepoints Intro EFCore 5中引入了一个新特性,叫做 Savepoints,主要是事务中使用,个人感觉有点类似于 Windows 上的系统还原点,如果事务 ...
- 运用 pyinstaller 打包的python exe文件运行 去掉命令行窗口及其他参数汇总
运行exe文件的时候,会弹出一个dos命令窗口,这个窗口可以看到一些打印信息,如果想只运行tkinter 页面,去掉dos窗口需要在打包的时候 加上 -w 参数 pyinstaller -F XX.p ...
- 抛弃 .NET 经典错误:object null reference , 使用安全扩展方法? 希望对大家有帮助---Bitter.Frame 引用类型的安全转换
还是一样,我不喜欢长篇大论,除非关乎我设计思想领域的文章.大家过来看,都是想节省时间,能用白话表达的内容,绝不长篇大论.能直接上核心代码的,绝不上混淆代码. 长期从事 .NET 工作的人都知道..NE ...
- Maven 本地仓库
概述 Maven 的本地资源库是用来存储所有项目的依赖关系(插件 Jar 和其他文件,这些文件被 Maven 下载)到本地文件夹.很简单,当你建立一个 Maven 项目,所有相关文件将被存储在你的 M ...
- (SqlServe)关于字符串长度被截断的问题
1. 问题描述 在同步数据时常常会发现一个错误:将截断字符串或二进制数据. 2. 问题原因 这个问题出现的原因是:要插入的数值字段的长度超出了数据库中字段的长度.比如:插入的字符串字节长度是40,数据 ...
- 「NOIP2009」最优贸易
「NOIP2009」最优贸易 「NOIP2009」最优贸易内存限制:128 MiB时间限制:1000 ms 题目描述C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意 ...