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. 解决IE apk变成zip:Android 手机应用程序文件下载服务器 配置解决方法

    APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以看到Dex文件,Dex是Dalvik VM executes的全称,即Android Dalvik执行程序,并非Java ...

  2. ECSHOP管理员密码忘记了怎么办?

    ECSHOP管理员密码忘记了怎么办? ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2013-09-06   不小心在后台把管理员全部给清空了,闹的网站都无法登陆了?有 ...

  3. event.keycode值大全

    window.event.keycode-获取按下的键盘值   event.keycode值大全1 keycode 8 = BackSpace BackSpace 2 keycode 9 = Tab ...

  4. WPF捕捉Windows关机事件

    private const int SC_SCREENSAVE = 0xF140; private const int WM_QUERYENDSESSION = 0x0011; private boo ...

  5. C++中 :: 的意思

    表示作用域,和所属关系 ::是运算符中等级最高的,它分为三种:1)global scope(全局作用域符),用法(::name)2)class scope(类作用域符),用法(class::name) ...

  6. Pb (数据存储单位)

    PB (数据存储单位) 编辑 pb指petabyte,它是较高级的存储单位,其上还有EB,ZB,YB等单位. 它等于1,125,899,906,842,624(2的50次方)字节,“大约”是一千个te ...

  7. malloc 函数到底做了什么?

    请看下面的代码. 猜测结果是什么?编译通过吗? #include <stdio.h> #include <stdlib.h> int main() { ; char *ptr ...

  8. TYVJ1460 旅行

    描述 A国有n座城市,每座城市都十分美,这使得A国的民众们非常喜欢旅行.然而,A国的交通十分落后,这里只有m条双向的道路,并且这些道路都十分崎岖,有的甚至还是山路,只能靠步行.通过每条道路的长度.泥泞 ...

  9. POJ 3464 ACM Computer Factory

    ACM Computer Factory Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4829 Accepted: 1641 ...

  10. 淘宝(阿里百川)手机客户端开发日记第六篇 Service详解(二)

    DEMO1:当我们点击启动服务时和点击停止服务的时候,观察服务的运行状态,布局由于简单,只是两个普通的Button按钮,在此我只上截图. java代码部分 第一步:我们需要实现一个服务类,继承自ser ...