题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430

题意:给你n个编码后的模式串,和m个编码后的主串,求原来主串中含有模式串的个数

思路:首先要将模式串解码成未编码前来建立ac自动机,然后解码主串扫描统计即可。

code:

 #include <cstdio>
#include <cstring>
#include <queue>
#include <set>
using namespace std;
const int KIND = ;
const int MAXN = ; struct Trie
{
int next[MAXN][KIND], fail[MAXN], id[MAXN];
int root, L, num;
int create()
{
for (int i = ; i < KIND; ++i)
next[L][i] = -;
return L++;
}
void init()
{
L = ;
num = ;
memset(id, , sizeof(id));
root = create();
}
void insert(unsigned char str[], int len)
{
int now = root;
for (int i = ; i < len; ++i)
{
if (- == next[now][str[i]])
next[now][str[i]] = create();
now = next[now][str[i]];
}
id[now] = ++num;
}
void build()
{
queue<int>Q;
fail[root] = root;
for (int i = ; i < KIND; ++i)
{
if (- == next[root][i])
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
}
while (!Q.empty())
{
int now = Q.front();
Q.pop();
for (int i = ; i < KIND; ++i)
{
if (- == next[now][i])
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
}
int query(unsigned char str[], int len)
{
set<int>S;
int now = root;
for (int i = ; i < len; ++i)
{
now = next[now][str[i]];
int temp = now;
while (temp != root)
{
if (id[temp]) S.insert(id[temp]);
temp = fail[temp];
}
}
return (int)S.size();
}
}; Trie ac;
char buf[];
unsigned char temp[];
unsigned char str[]; unsigned char Tran(char ch)
{
if (ch >= 'A' && ch <= 'Z') return ch - 'A';
if (ch >= 'a' && ch <= 'z') return ch - 'a' + ;
if (ch >= '' && ch <= '') return ch - '' + ;
if (ch == '+') return ;
return ;
} int Decode(int len)
{
int k = ;
for (int i = ; i < len; i += )
{
str[k++] = (temp[i]<<)|(temp[i + ]>>);
if (i + < len) str[k++] = (temp[i + ]<<)|(temp[i + ]>>);
if (i + < len) str[k++] = (temp[i + ]<<)|(temp[i + ]);
}
return k;
} int main()
{
int n, m;
while (scanf("%d", &n) != EOF)
{
ac.init();
for (int i = ; i <n; ++i)
{
scanf("%s", buf);
int len = strlen(buf);
while ('=' == buf[len - ]) --len;
for (int j = ; j < len; ++j) temp[j] = Tran(buf[j]);
ac.insert(str, Decode(len));
}
ac.build();
scanf("%d", &m);
for (int i = ; i < m; ++i)
{
scanf("%s", buf);
int len = strlen(buf);
while ('=' == buf[len - ]) --len;
for (int j = ; j < len; ++j) temp[j] = Tran(buf[j]);
printf("%d\n", ac.query(str, Decode(len)));
}
printf("\n");
}
return ;
}

ZOJ 3430 Detect the Virus(AC自动机)的更多相关文章

  1. ZOJ - 3430 Detect the Virus —— AC自动机、解码

    题目链接:https://vjudge.net/problem/ZOJ-3430 Detect the Virus Time Limit: 2 Seconds      Memory Limit: 6 ...

  2. zoj 3430 Detect the Virus(AC自己主动机)

    题目连接:zoj 3430 Detect the Virus 题目大意:给定一个编码完的串,将每个字符相应着表的数值转换成6位二进制.然后以8为一个数值,又一次形成字符 串,推断给定询问串是否含有字符 ...

  3. ZOJ 3430 Detect the Virus

    传送门: Detect the Virus                                                                                ...

  4. zoj 3430 Detect the Virus(AC自己主动机)

    Detect the Virus Time Limit: 2 Seconds      Memory Limit: 65536 KB One day, Nobita found that his co ...

  5. ZOJ 3430 Detect the Virus 【AC自动机+解码】

    解码的那些事儿,不多说. 注意解码后的结果各种情况都有,用整数数组存储,char数组会超char类型的范围(这个事最蛋疼的啊)建立自动机的时候不能用0来判断结束. #include <cstdi ...

  6. ZOJ 3430 Detect the Virus(AC自动机 + 模拟)题解

    题意:问你主串有几种模式串.但是所有串都是加密的,先解码.解码过程为:先把串按照他给的映射表变成6位数二进制数,然后首尾衔接变成二进制长串,再8位8位取变成新的数,不够的补0.因为最多可能到255,所 ...

  7. ZOJ 3228 Searching the String(AC自动机)

    Searching the String Time Limit: 7 Seconds      Memory Limit: 129872 KB Little jay really hates to d ...

  8. ZOJ 4114 Detect the Virus(AC自动机)

    Detect the Virus Time Limit: 2 Seconds      Memory Limit: 65536 KB One day, Nobita found that his co ...

  9. ZOJ 3494 BCD Code(AC自动机 + 数位DP)题解

    题意:每位十进制数都能转化为4位二进制数,比如9是1001,127是 000100100111,现在问你,在L到R(R <= $10^{200}$)范围内,有多少数字的二进制表达式不包含模式串. ...

随机推荐

  1. 一个Windows C++的线程类实现

    Thread.h [cpp] view plaincopy #ifndef __THREAD_H__ #define __THREAD_H__ #include <string> #inc ...

  2. current imporant Posts

    CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete) http://www.centos.org/docs/5/htm ...

  3. javascript编辑器预览模式解密

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. C++中的随机数函数(

    标签:ul 随机数 c 整数 max 教育  C++中产生随机数种子对于刚開始学习的人一直都非常困惑.大家知道,在C中有专门的srand(N)函数能够轻松实现这一功能,然而在C++中则要复杂一些.以下 ...

  5. html中radio,checkbox值的获取、赋值、注册事件

    1,radio分组 只要name一样,就是一组的,即一组中只能选择一个,如下: 代码如下: <span>group1:</span> <input type=" ...

  6. ORA-03113: 通信通道的文件结尾 进程 ID: 764 会话 ID: 125 序列号: 5

    昨天因为导入很久数据,最后一看是因为数据文件不够,后来就关机了.现在,开启数据库,总是报“ORA-03113: 通信通道的文件结尾” SQL> conn /as sysdba; 已连接到空闲例程 ...

  7. C#中的ref与out参数(本文仅作为个人笔记)

    假如一个方法的参数(形参)是引用类型,那么使用那个参数来进行的任何修改都会改变参数引用的数据.但这里的关键在于,虽然引用的数据发生了变化,但参数本生没有改变——它仍然引用的是一个对象.换句话说,虽然可 ...

  8. [C#参考]细说进程、应用程序域与上下文之间的关系

    原文转载链接:http://www.cnblogs.com/leslies2/archive/2012/03/06/2379235.html Written by:风尘浪子 引言 本文主要是介绍进程( ...

  9. Django Web开发【3】创建网络收藏夹

    这一节我们将继续一个创建网络收藏夹应用,并学习视图.模型以及模板的处理过程. Django是一个MVC开发框架,但是它的控制器对应的为view,而视图对应为模板(template),模型对应model ...

  10. bzoj 1066 : [SCOI2007]蜥蜴 网络流

    题目链接 给一个n*m的图, 里面每一个点代表一个石柱, 石柱有一个高度. 初始时有些石柱上面有蜥蜴, 蜥蜴可以跳到距离他曼哈顿距离小于等于d的任意一个石柱上,跳完后, 他原来所在的石柱高度会减一, ...