Description

Aliens on planet Pandora also write computer programs like us. Their programs only consist of capital letters (‘A’ to ‘Z’) which they learned from the Earth. On planet Pandora, hackers make computer virus, so they also have anti-virus software. Of course they learned virus scanning algorithm from the Earth. Every virus has a pattern string which consists of only capital letters. If a virus’s pattern string is a substring of a program, or the pattern string is a substring of the reverse of that program, they can say the program is infected by that virus. Give you a program and a list of virus pattern strings, please write a program to figure out how many viruses the program is infected by.

Input

There are multiple test cases. The first line in the input is an integer T ( T <= 10) indicating the number of test cases. 
For each test case: 
The first line is a integer n( 0 < n <= 250) indicating the number of virus pattern strings. 
Then n lines follows, each represents a virus pattern string. Every pattern string stands for a virus. It’s guaranteed that those n pattern strings are all different so there are n different viruses. The length of pattern string is no more than 1,000 and a pattern string at least consists of one letter. 
The last line of a test case is the program. The program may be described in a compressed format. A compressed program consists of capital letters and “compressors”. A “compressor” is in the following format: 
[qx] 
q is a number( 0 < q <= 5,000,000)and x is a capital letter. It means q consecutive letter xs in the original uncompressed program. For example, [6K] means ‘KKKKKK’ in the original program. So, if a compressed program is like: 
AB[2D]E[7K]G 
It actually is ABDDEKKKKKKKG after decompressed to original format.  The length of the program is at least 1 and at most 5,100,000, no matter in the compressed format or after it is decompressed to original format.

Output

For each test case, print an integer K in a line meaning that the program is infected by K viruses.

题目大意:给n个模式串,一个长串,问有多少个模式串出现在了长串中(翻转后的模式串也算)。

思路:多模式串匹配,裸的AC自动机题。对于一个模式串可能会是另一个模式串的子串的问题,只要每走一步之后把失配指针都走一下即可。不过据说都走一下会超时,所以要给每个点做一个标记,标记这个点的走过了,不用再走一次了。

PS:用指针的孩纸不回收内存会MLE,亲测……

PS2:题目好像没说一个串不能是另一个串的子串,但是我之前没考虑子串(只考虑了一个串是另一个串的后缀)依然AC了……

代码(HDU 1593MS/POJ 1671MS):

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std; const int MAXN = ;
const int MAX = ; struct Node {
Node *go[], *fail;
int src;
bool mark;
Node(int _src) {
src = _src;
fail = ; mark = ;
memset(go, , sizeof(go));
}
~Node() {
for(int i = ; i < ; ++i)
if(go[i]) delete go[i];
}
}; void build(Node *root, char *str, int id) {
Node *p = root;
for(int i = ; str[i]; ++i) {
int index = str[i] - 'A';
if(!p->go[index]) p->go[index] = new Node(-);
p = p->go[index];
}
p->src = id;
} void makeFail(Node *root) {
queue<Node*> que;que.push(root);
while(!que.empty()) {
Node *tmp = que.front(); que.pop();
for(int i = ; i < ; ++i) {
if(!tmp->go[i]) continue;
if(tmp == root) tmp->go[i]->fail = root;
else {
Node *p = tmp->fail;
while(p) {
if(p->go[i]) {
tmp->go[i]->fail = p->go[i];
break;
}
p = p->fail;
}
if(!p) tmp->go[i]->fail = root;
}
que.push(tmp->go[i]);
}
}
root->fail = root;
} bool vis[]; void solve(Node *root, char *str) {
Node *tmp = root;
for(char *now = str; *now; ++now) {
int index = *now - 'A';
while(tmp != root && !tmp->go[index]) tmp = tmp->fail;
if(tmp->go[index]) tmp = tmp->go[index];
Node *q = tmp;
while(q != root && !q->mark) {
q->mark = true;
if(q->src > ) vis[q->src] = true;
q = q->fail;
}
}
} int make_ans(int n) {
int ret = ;
for(int i = ; i <= n; ++i)
ret += vis[i];
return ret;
} void trans(char *ss, char *tt) {
for(int i = ; ss[i]; ++i) {
if(isalpha(ss[i])) *tt++ = ss[i];
else {
++i;
int t = ;
while(isdigit(ss[i])) t = t * + ss[i] - '', ++i;
for(int j = ; j < t; ++j) *tt++ = ss[i];
++i;
}
}
*tt = ;
} char ss[MAXN], s[MAXN];
char tmp[MAX]; int main() {
int T, n;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
Node *root = new Node(-);
for(int i = ; i <= n; ++i) {
scanf("%s", tmp);
build(root, tmp, i);
reverse(tmp, tmp + strlen(tmp));
build(root, tmp, i);
}
makeFail(root);
scanf("%s", ss);
trans(ss, s);
//printf("%s\n", s);
memset(vis, , sizeof(vis));
solve(root, s);
printf("%d\n", make_ans(n));
delete root;
}
}

HDU 3695 / POJ 3987 Computer Virus on Planet Pandora(AC自动机)(2010 Asia Fuzhou Regional Contest)的更多相关文章

  1. HDU 3695 / POJ 3987 Computer Virus on Planet Pandora

      Computer Virus on Planet Pandora Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1353 ...

  2. POJ 3987 Computer Virus on Planet Pandora (AC自动机优化)

    题意 问一个字符串中包含多少种模式串,该字符串的反向串包含也算. 思路 解析一下字符串,简单. 建自动机的时候,通过fail指针建立trie图.这样跑图的时候不再跳fail指针,相当于就是放弃了fai ...

  3. hdu ----3695 Computer Virus on Planet Pandora (ac自动机)

    Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 256000/1280 ...

  4. HDU3695 - Computer Virus on Planet Pandora(AC自动机)

    题目大意 给定一个文本串T,然后给定n个模式串,问有多少个模式串在文本串中出现,正反都可以 题解 建立好自动机后.把文本串T正反各匹配一次,刚开始一直TLE...后面找到原因是重复的子串很多以及有模式 ...

  5. HDU 3699 A hard Aoshu Problem(暴力枚举)(2010 Asia Fuzhou Regional Contest)

    Description Math Olympiad is called “Aoshu” in China. Aoshu is very popular in elementary schools. N ...

  6. hdu 3695 Computer Virus on Planet Pandora(AC自己主动机)

    题目连接:hdu 3695 Computer Virus on Planet Pandora 题目大意:给定一些病毒串,要求推断说给定串中包括几个病毒串,包括反转. 解题思路:将给定的字符串展开,然后 ...

  7. HDU 3698 Let the light guide us(DP+线段树)(2010 Asia Fuzhou Regional Contest)

    Description Plain of despair was once an ancient battlefield where those brave spirits had rested in ...

  8. HDU 3697 Selecting courses(贪心+暴力)(2010 Asia Fuzhou Regional Contest)

    Description     A new Semester is coming and students are troubling for selecting courses. Students ...

  9. HDU 3696 Farm Game(拓扑+DP)(2010 Asia Fuzhou Regional Contest)

    Description “Farm Game” is one of the most popular games in online community. In the community each ...

随机推荐

  1. ecshop后台admin路径怎么修改

    ecshop后台admin路径怎么修改 ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2013-03-25   ecshop如何修改后台admin路径? 大家都知道ec ...

  2. javascript面向对象方式,调用属性和方法

    1.定义一个Person类,其中的属性和方法如果想对外开放,需要使用this,如: var Person=function(name,age,sex){ var psex='Boy'; if(sex) ...

  3. 锋利的jQuery-4--$(document).ready()和window.onload方法的区别

    jQuery中的$(document).ready()和JavaScript中的window.onload方法主要有两个方面的不同: 1.执行时机: onload : 网页中所有的元素和元素的关联文件 ...

  4. memcache的内存回收机制

    memcache不会释放内存,而是重新利用. 在缓存的清除方面,memcache是不释放已分配内存.当已分配的内存所在的记录失效后,这段以往的内存空间,memcache只会重复利用. memcache ...

  5. Toast工具类,Android中不用再每次都写烦人的Toast了

    package com.zhanggeng.contact.tools; /** * Toasttool can make you use Toast more easy ; * * @author ...

  6. mongo数据库的导入导出

    http://www.iwangzheng.com/ [root@a02]$show dbs; changhong_tv_cms 0.078GB [root@a02]$ mongodump -d ch ...

  7. vim中的查找和替换

    (文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) 查找: Gsearch -F 'aa' -R  --include=*rb 替换: (1)在查找结果 ...

  8. Populating Next Right Pointers in Each Node

    这题代码简单,不过不容易想到. void connect(TreeLinkNode *root) { if (root == nullptr ||root->left==nullptr)retu ...

  9. apache2:Invalid option to WSGI daemon process definition

    版本说明: ubuntu 12.04 server /apache 2.2 / mod_wsgi 3.3 / python 2.7.3 /django 1.7 在ubuntu12的服务器上配置djan ...

  10. NOIP 2014 pj & tg

    由于我太弱,去了pj组= = ============================== T1: 傻逼暴力 T2: 傻逼暴力+判断+更新 T3: 手画一下就知道了.算出这个点在第几圈,再使劲yy下在 ...