本题是在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自己主动机题解的更多相关文章

  1. HDU 2896 病毒侵袭 (AC自己主动机)

    pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...

  2. hdu 2896 病毒侵袭 ac自动机

    /* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...

  3. hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  4. hdu 2896 病毒侵袭 AC自动机 基础题

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. POJ 3691 &amp; 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: ...

  6. HDU 2825 Wireless Password (AC自己主动机,DP)

    pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...

  7. hdu 2222 Keywords Search ac自己主动机

    点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

  8. HDU - 2825 Wireless Password(AC自己主动机+DP)

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...

  9. HDU 2222 Keywords Search AC自己主动机入门题

    单词统计的题目,给出一些单词,统计有多少单词在一个文本中出现,最经典的入门题了. AC自己主动机的基础: 1 Trie. 以这个数据结构为基础的,只是添加一个fail指针和构造fail的函数 2 KM ...

随机推荐

  1. Flask中路由模块的实现

    在Flask中的路由功能主要通过修饰函数route实现,下面我们就来挖掘下route在源代码中是怎么分配视图函数的. def route(self, rule, **options): def dec ...

  2. Windows Phone 8初学者开发—第13部分:设置LongListSelector中磁贴的样式

    原文 Windows Phone 8初学者开发—第13部分:设置LongListSelector中磁贴的样式 第13部分:设置LongListSelector中磁贴的样式 原文地址: http://c ...

  3. linux grep详解

    Table of Contents 1. grep简介 2. grep正则表达式元字符集(基本集) 3. 用于egrep和 grep -E的元字符扩展集 4. POSIX字符类 5. Grep命令选项 ...

  4. C语言中没有main函数生成可执行程序的几种方法

    1.define预处理指令 这种方式很简单,只是简单地将main字符串用宏来代替,或者使用##拼接字符串.示例程序如下: #include <stdio.h> #define begin ...

  5. 详细解析BluetoothAdapter的详细api

    (1)开关状态值 (2)扫描状态值 (3)蓝牙操作接收的广播 (4)蓝牙操作请求的广播 (5)附加域 (6)错误码 (1)获取蓝牙适配器 (2)获取state状态方法 (3)蓝牙是否可用 (4)打开蓝 ...

  6. (void)(&amp;x==&amp;y)

    #define max(x,y) ({ \ typeof(x) _x = (x);    \ typeof(y) _y = (y);    \ (void) (&_x == &_y); ...

  7. python下的web服务器模块

    python下的web服务模块有三种: BaseHTTPServer: 提供基本的Web服务和处理器类,分别是HTTPServer和BaseHTTPRequestHandler SimpleHTTPS ...

  8. stm32之GPIO

    stm32有5组GPIO口,GPIOA GPIOB GPIOC GPIOD GPIOE 每个GPIO端口有: 2个配置寄存器GPIOx_CRL, GPIOx_CRH(32位): 2个数据寄存器GPIO ...

  9. JS - 删除确认

    <a href="javascript:if(confirm('确实要删除吗?'))location='<{:U('Admin/Update/deleteuserinfo', a ...

  10. jQuery prop 全选和全不全

    $('#ckAll').click(function() { var value = $(this).is(':checked') ? true : false; $("input[name ...