HDU 2896 病毒侵袭 AC自己主动机题解
本题是在text里面查找key word的增强版。由于这里有多个text。
那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术。我直接使用个vis数组记录已经訪问过的节点,达到加速效果,速度还算挺快的。
只是看discuss里面有人直接使用Trie,做出了140ms的速度,并且他的程序严格来说并不对。可见本题的数据非常水啊。Trie的时间效率肯定比AC自己主动机低,可是在数据非常水的特殊情况下。Trie的速度也能够非常快的。
注意两个细节:
1 病毒也须要安装顺序输出,不小心就遗漏了。这里害我错了几次。
2 还有就是题目的字符不确定是多少。使用33-94范围的字符測试答案正确的。
#include <stdio.h>
#include <string.h>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;
const int MAX_N = 501;
const int MAX_WORD = 201;
const int MAX_M = 1001;
const int MAX_TXT = 10001;
const int MAX_V = 3;
const int ARR_SIZE = 94;
char virus[MAX_WORD], web[MAX_TXT];
int webNum[MAX_V];
int M, N; inline int getIndex(char ch) { return ch - 33; } struct Node
{
int n, num, id;
Node *fail;
Node *arr[ARR_SIZE];
}; void clearNode(Node *rt)
{
rt->n = 0;
rt->num = 0;
rt->id = 0;
rt->fail = NULL;
for (int i = 0; i < ARR_SIZE; i++)
{
rt->arr[i] = NULL;
}
} Node gPool[MAX_N*MAX_WORD], *Trie;
int gPoolID;
bool vis[MAX_N*MAX_WORD]; //怎么老是忘记使用visited技术的? void insertTrie(char *virus, int num)
{
Node *pCrawl = Trie;
for (; *virus; virus++)
{
int id = getIndex(*virus);
if (!pCrawl->arr[id])
{
pCrawl->arr[id] = &gPool[gPoolID++];
clearNode(pCrawl->arr[id]);
pCrawl->arr[id]->id = gPoolID-1;
}
pCrawl = pCrawl->arr[id];
}
pCrawl->n++;
pCrawl->num = num;
} void buildFail()
{
queue<Node *> qu;
qu.push(Trie);
while (!qu.empty())
{
Node *p = qu.front(); qu.pop();
for (int i = 0; i < ARR_SIZE; i++)
{
if (!p->arr[i]) continue;
p->arr[i]->fail = Trie;
Node *fail = p->fail;
while (fail)
{
if (fail->arr[i])
{
p->arr[i]->fail = fail->arr[i];
break;
}
fail = fail->fail;
}
qu.push(p->arr[i]);
}
}
} int searchVirus(char *web)
{
int n = 0;
Node *pCrawl = Trie;
memset(vis, 0, sizeof(bool)*(gPoolID+1));
for (; *web; web++)
{
int i = getIndex(*web);
while (!pCrawl->arr[i] && pCrawl != Trie) pCrawl = pCrawl->fail;
if (pCrawl->arr[i])
{
pCrawl = pCrawl->arr[i];
Node *p = pCrawl;
while (p && !vis[p->id])//使用vis比直接检查数组值快捷方便
{
if (p->n) webNum[n++] = p->num;
vis[p->id] = true;
p = p->fail;
}
if (n == MAX_V) break; //At most MAX_V virus one web
}
}
return n;
} int main()
{
Trie = &gPool[0];
while (scanf("%d", &N) != EOF)
{
gPoolID = 1;
clearNode(Trie);
getchar();
for (int i = 1; i <= N; i++)
{
gets(virus);
insertTrie(virus, i);
}
buildFail(); scanf("%d", &M);
getchar();
int cnt = 0;
for (int i = 1; i <= M; i++)
{
gets(web);
int n = searchVirus(web);
if (n)
{
cnt++;
printf("web %d:", i); sort(webNum, webNum + n);//Watch out: order!
for (int j = 0; j < n; j++)
{
printf(" %d", webNum[j]);
}
putchar('\n');
}
}
printf("total: %d\n", cnt);
}
return 0;
}
HDU 2896 病毒侵袭 AC自己主动机题解的更多相关文章
- HDU 2896 病毒侵袭 (AC自己主动机)
		
pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...
 - hdu 2896 病毒侵袭 ac自动机
		
/* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...
 - hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)
		
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
 - hdu 2896 病毒侵袭 AC自动机 基础题
		
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
 - POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
		
http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...
 - HDU 2825 Wireless Password (AC自己主动机,DP)
		
pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...
 - hdu 2222 Keywords Search ac自己主动机
		
点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
 - HDU - 2825 Wireless Password(AC自己主动机+DP)
		
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
 - HDU 2222 Keywords Search AC自己主动机入门题
		
单词统计的题目,给出一些单词,统计有多少单词在一个文本中出现,最经典的入门题了. AC自己主动机的基础: 1 Trie. 以这个数据结构为基础的,只是添加一个fail指针和构造fail的函数 2 KM ...
 
随机推荐
- gcc代码反汇编查看内存分布[1]: gcc
			
# gcc -vgcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) 重点: 代码中的内存分配, 地址从低到高: 代码段(RO, 保存函数代码) --&g ...
 - OpenCV 安装
			
OpenCV 安装 一.环境说明: 操作系统:window10 opencv版本是:VERSION3.1 二.安装过程: [1]官网下载:http://opencv.org/downloads.htm ...
 - Oracle 如何写出高效的 SQL
			
转自:Oracle 如何写出高效的 SQL 要想写出高效的SQL 语句需要掌握一些基本原则,如果你违反了这些原则,一般情况下SQL 的性能将会很差. 1. 减少数据库访问次数连接数据库是非常耗时的,虽 ...
 - 关于java中强制转换
			
在百度上遇到一个问题,描述如下: 在java中,定义两个变量 byte x = (byte) 128; byte y = (byte)-129; 输出后,为什么结果是-128和128? 借此机会,自己 ...
 - QT动画介绍(有例子可以下载)
			
所谓动画就是在一个时间段内的不同时间点有不同的状态,只要定义好这样状态,实现动画就是水到渠成的事情.当然做这件事情,最好用的就是状态机,点击这里查看Qt使用状态机实现动画效果实例. 不过,实现动画也有 ...
 - [Unity 3D] Unity 3D 性能优化(二)
			
IsAlive U3D的粒子系统脚本接口相信很多人都用过,ParticleSyetem类的一系列接口都有一个bool类型的参数——withChildren,通过这个参数可以直接将相同的判断或者操作应用 ...
 - C# 中datagridview行里面有三个cheeckbox,要控制成三选一。
			
我之前有试过在cellendedit中处理,可以达成效果,当不符合用户打单的界面要求.该事件是在单元格编辑结束之后, 当用户选中两个checkbox,且焦点不移开时,界面上会出现有两个checkbox ...
 - Linux内核态抢占机制分析(转)
			
Linux内核态抢占机制分析 http://blog.sina.com.cn/s/blog_502c8cc401012pxj.html 摘 要]本文首先介绍非抢占式内核(Non-Preemptive ...
 - Spring MVC 3.x 版本使用 @ResponseBody 返回乱码
			
由于万恶的Spring MVC 默认返回编码 是 ISO-8859-1, 使用如下配置, 可以将编码专为UTF-8, <bean class="org.springframework. ...
 - 乐观锁&悲观锁
			
悲观&乐观,只是对数据加锁的时机与粒度. 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这 ...