病毒侵袭 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的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒 ...
随机推荐
- 终于可以愉快的撸Java异步代码了!
异步响应式编程可以极大的提高系统的并发呑吐量,但由于Java没有类似于其他语言的Async/Await机制,所以只能通过CompletableFuture.thenXXX()来串联各个异步任务,这 ...
- K8s 平台可以如何处理 Pod 预授权问题
前言 TKEx-CSIG 是基于腾讯公有云 TKE 和 EKS 容器服务开发的内部上云容器服务平台,为解决公司内部容器上云提供云原生平台,以兼容云原生.适配自研业务.开源协同为最大特点. 业务容器上云 ...
- 【Oracle】表空间配额问题
由于需求,需要新建用户,但是新建的用户,会有相关的配额跟着,莫名其妙的问题让人很头疼 下面介绍下如何修改成不限制配额 select * from user_ts_quotas ; alter user ...
- Java程序入门
编写Java源程序 在d:\day01 目录下新建文本文件,完整的文件名修改为HelloWorld.java ,其中文件名为HelloWorld ,后缀名必须为.java . 用记事本打开 在文件中键 ...
- mysql主从复制安装配置
mysql主从复制安装配置 基础设置准备 #操作系统: centos6.5 #mysql版本: 5.7 #两台虚拟机: node1:192.168.182.111(主) node2:192.168.1 ...
- 提供个HDFS的目录的路径,对该目录进行创建和删除操作。创建目录时,如果目录 文件所在目录不存在则自动创建相应目录;删除目录时,由用户指定当该目录不为空时是否还删 除该目录
import java.io.IOException; import java.util.Scanner; import org.apache.hadoop.fs.*; public class G_ ...
- QQ好友状态,QQ群友状态,究竟是推还是拉? 网页端收消息,究竟是推还是拉?
https://mp.weixin.qq.com/s/KB1zdKcsh4PXXuJh4xb_Zw 网页端收消息,究竟是推还是拉? 原创 58沈剑 架构师之路 2020-12-28 https:/ ...
- 支持 gRPC 长链接,深度解读 Nacos 2.0 架构设计及新模型
支持 gRPC 长链接,深度解读 Nacos 2.0 架构设计及新模型 原创 杨翊(席翁) 阿里巴巴云原生 2020-12-28
- 找出10000内的素数 CSP
"Problem: To print in ascending order all primes less than 10000. Use an array of processes, SI ...
- Power of Two Choices 负载均衡
NGINX and the "Power of Two Choices" Load-Balancing Algorithm - NGINX https://www.nginx.co ...