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. something about english

    Molten lava from a volcano will solidify as it cools. The shuttle bus makes my commute to work conve ...

  2. 15个Linux Wget下载实例终极指南

    15个Linux Wget下载实例终极指南 Linux wget是一个下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,尤其对于网络管理员,经常要下载一些软件或从远程服务器恢复备份到 ...

  3. ASP.NET MVC4 log4net

    LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

  4. Objective-C 之优雅的命名(转)

    There are only two hard things in Computer Science: cache invalidation and naming things. 在计算机科学中只有两 ...

  5. hdu 5183. Negative and Positive (哈希表)

    Negative and Positive (NP) Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  6. CocoStudio基础教程(4)骨骼动画的动态换肤

    1.概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现. 2.运行到程序 ...

  7. Python ===if while for语句 以及一个小小网络爬虫实例

    if分支语句 >>> count=89 >>> if count==89: print count 89                          #单分支 ...

  8. LR 测试数据库总结

    今天工作中需要对mysql进行性能测试 我尝试用LR来做:但是mysql需要现在电脑上安装一个OBDC的mysql驱动器,然后在电脑的管理工具中的数据源中加入这个mysql驱动,测试连接数据库成功,O ...

  9. stringbuffer 和 stringbuilder的区别

    1. stringbuffer 和 stringbuilder的区别 StringBuffer是线程安全的, 这个类里的所有方法是同步的.这个反过来就会对程序的性能有一定的影响.StringBuild ...

  10. nginx: [emerg] getpwnam(“www”) failed

    在配置nginx 时提示如下错误时:nginx: [emerg] getpwnam(“www”) failed 解决方案一 在nginx.conf中 把user nobody的注释去掉既可 解决方案二 ...