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 ...
随机推荐
- float与position
使用float会使块级元素的宽高表现为包裹内容(在不设定宽高的情况下) 这是当然的 我们使用float就是使几个div排在一行 当然不可能在宽度上撑满父元素啦 至于高度 不论有没有float 高 ...
- js中的一元运算符
一元运算符只有一个参数,即要操作的对象或值.它们是 ECMAScript 中最简单的运算符. delete delete 运算符删除对以前定义的对象属性或方法的引用.例如: var o = new O ...
- Qt 技巧: 解决未解析的SSL问题
因为https访问需要用到SSL认证,而QT默认是不支持SSL认证,所以在使用之前必须先做一些准备工作: 需要安装OpenSSL库: 1.首先打开http://slproweb.com/product ...
- Multiple markers at this line @Override的解决方法
Multiple markers at this line - implements java.awt.event.ActionListener.actionPerformed - The metho ...
- strut2服务器与android交互数据
libs如图: web.xml: <?xml version="1.0" encoding="UTF-8"?> <web-app versio ...
- splice()函数的使用方法
splice()函数的使用方法,这是一个拗口的函数.用起来有点麻烦.图3所看到的是splice函数的功能.将一个列表插入到还有一个列表其中.list容器类定义了splice()函数的3个版本号: sp ...
- XMPP个人信息展示
在现阶段的通信服务中.各种标准都有,因此会出现无法实现相互连通,而XMPP(Extensible Message and presence Protocol)协议的出现.实现了整个及时通信服务协议的互 ...
- SRBF Lighting
SRBF的全称是Spherical Radial Basis Function,笔者擅自翻译为球面放射基底函数.由于SRBF并不怎么出名,相对来说,SH(Spherical Harmonic)球 ...
- HDU 3060 多边形面积并
Area2 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- Shell脚本运行hive语句 | hive以日期建立分区表 | linux schedule程序 | sed替换文件字符串 | shell推断hdfs文件文件夹是否存在
#!/bin/bash source /etc/profile; ################################################## # Author: ouyang ...