hdoj 3065 病毒侵袭持续中(AC自动机)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065
思路分析:问题需要模式匹配多个模式串,需要注意的是模式串会包含和重叠,需要对AC自动机的匹配过程进行修改,对于每个节点,需要从该节点的失败指针回溯,
如果失败指针回溯后的节点为某个模式串的最后一个节点,则匹配了另一个模式串;
代码如下:
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int KIND = ;
const int MAX_NODE = * ;
const int MAX_N = + ;
const int MAX_M = + ;
char str[MAX_M];
int visited[MAX_N];
int vir_match[MAX_N];
char vir[MAX_N][]; struct Trie {
int root, count;
int next[MAX_NODE][KIND], fail[MAX_NODE], end[MAX_NODE];
void Init()
{
count = ;
root = NewNode();
}
int NewNode()
{
for (int i = ; i < KIND; ++i)
next[count][i] = -;
end[count] = -;
return count++;
} void Insert(char *str, int id)
{
int i = , k = ;
int now = root; while (str[i])
{
k = str[i];
if (next[now][k] == -)
next[now][k] = NewNode();
now = next[now][k];
++i;
}
end[now] = id;
} void BuildAutomaton()
{
queue<int> Q; fail[root] = -;
Q.push(root);
while (!Q.empty())
{
int now = Q.front();
int p = -;
Q.pop(); for (int i = ; i < KIND; ++i)
{
if (next[now][i] != -)
{
if (now == root)
fail[next[now][i]] = root;
else
{
p = fail[now];
while (p != -)
{
if (next[p][i] != -)
{
fail[next[now][i]] = next[p][i];
break;
}
p = fail[p];
}
if (p == -)
fail[next[now][i]] = root;
}
Q.push(next[now][i]);
}
}
}
} int Match(char *str)
{
int i = , k = , vir_count = ;
int p = root; while (str[i])
{
k = str[i];
while (next[p][k] == - && p != root)
p = fail[p];
p = next[p][k];
p = (p == -) ? root : p; int temp = p;
while (temp != root)
{
if (end[temp] != -)
{
if (visited[end[p]] == )
vir_match[vir_count++] = end[p];
visited[end[p]]++;
}
temp = fail[temp];
}
++i;
}
return vir_count;
}
};
Trie root; int main()
{
int vir_num = ;
int match_count = ; while (scanf("%d\n", &vir_num) != EOF)
{
root.Init();
memset(vir_match, , sizeof(vir_match));
memset(visited, , sizeof(visited));
for (int i = ; i < vir_num; ++i)
{
gets(str);
strcpy(vir[i], str);
root.Insert(str, i + );
} match_count = ;
root.BuildAutomaton();
gets(str);
int ans = root.Match(str);
sort(vir_match, vir_match + ans);
if (ans)
{
for (int j = ; j < ans - ; ++j)
printf("%s: %d\n", vir[vir_match[j] - ], visited[vir_match[j]]);
printf("%s: %d\n", vir[vir_match[ans - ] - ],
visited[vir_match[ans - ]]);
}
}
return ;
}
hdoj 3065 病毒侵袭持续中(AC自动机)的更多相关文章
- HDU 3065 病毒侵袭持续中 (AC自动机)
题目链接 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒 ...
- hdu3065 病毒侵袭持续中 AC自动机入门题 N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。
/** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的 ...
- hdu----(3065)病毒侵袭持续中(AC自动机)
病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU3065 病毒侵袭持续中 —— AC自动机
题目链接:https://vjudge.net/problem/HDU-3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- HDU-3065 病毒侵袭持续中 AC自动机又是一板子!
病毒侵袭持续中 上一题是求出现多少病毒输出病毒序号,而这题输出每个病毒出现的次数.这题有字典树基础都能做出来,把叶子节点用相应的编号标记起来,匹配的时候遍历到叶子节点用一个数组把次数存起来就行了. 有 ...
- [hdu3065]病毒侵袭持续中(AC自动机)
题意:给出多种病毒的号码和特征码,计算在某串中各病毒匹配的次数. 解题关键:AC自动机模板题,多组输入坑人. #include<bits/stdc++.h> using namespace ...
- HDU 3065 病毒侵袭持续中
HDU 3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3065 病毒侵袭持续中【AC自动机】
<题目链接> 题目大意: 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的“万恶之源”.这是一个庞大的病毒网站,他有着好多好多的病毒,但是 ...
- HDU 3065 病毒侵袭持续中(AC自己主动机)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭 ...
随机推荐
- (C++编程规范第17条)避免使用”魔数“
1.摘要: 程序设计并非魔数,所以不要故弄玄虚:要避免在代码中使用诸如42和3.14159这样的文字常量.它们本身没有提供任何说明,并且因为增加了难于检测的重复而使维护更加复杂.可以用符号名称和表达式 ...
- EL表达式(Expression Language)
语法: ${Expression} 来取代难以维护的Java脚本元素,或笨拙的jsp:useBean和jsp:getProperty; 尤其重要的是,表达式语言支持下面的功能: 1.精确地访问存储对象 ...
- As Easy As A+B
Problem Description These days, I am thinking about a question, how can I get a problem as easy as A ...
- 为什么IIS中找不到.net framework 4.5(转)
.net 4.5是4.0的update,所以直接用4.0部署就可以了 .NET 4.5 is an in-place replacement for .NET 4.0, When .NET 4.5 i ...
- Ajax 调用方式
function wds_generatecss() { var txt = $.trim($("#TxtText").val()); if (txt == "" ...
- IE7.JS解决IE兼容性问题方法
转自:http://code.google.com/p/ie7-js/ 使IE5,IE6兼容到IE7模式(推荐) <!--[if lt IE 7]> <script src=&quo ...
- MYSQL 执行计划
Explain语法 EXPLAIN SELECT …… 变体: 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得 ...
- HDU 5729 Rigid Frameworks(连通性DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5729 [题目大意] 给出一个n*m的方格框,可以在单位矩形中添加两种对角线的线,使得其变得稳定,问 ...
- 补丁(patch)的制作与应用
命令简介 用到的两个命令是diff和patch. diff diff可以比较两个东西,并可同时记录下二者的区别.制作补丁时的一般用法和常见选项为: diff [选项] 源文件(夹) 目的文件(夹) - ...
- openStack 王者归来之 trivial matters
<一,openStack img 制作> tips:制作大部分cloud platforms img准备工作. <1,> http://www.pubyun.com/blog/ ...