题目链接: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. NOI2013 Day1

    NOI2013 Day1 向量内积 题目描述:两个\(d\)维向量\(A\)与\(B\)的内积为其相对应维度的权值的乘积和,现有\(n\)个\(d\)维向量 ,求是否存在两个向量的内积为\(k\)(\ ...

  2. redsocks 设置全局代理

    分享一下我的经验, http://lilydjwg.is-programmer.com/2014/2/7/linux-really-global-http-proxy.42701.html 1. 优点 ...

  3. jquery插件tab——小试牛刀

    <html> <head> <script type="text/javascript" src="http://ajax.googleap ...

  4. 分布式ElasticSearch简单介绍

    这里我们解释一些通用的术语,比如集群(cluster).节点(node)和分片(shard).Elasticsearch的扩展机制,以及它怎样处理硬件故障.在此将探索怎样创建你的集群(cluster) ...

  5. golang 之 defer(统计函数执行时间)

    package main import ( "fmt" "time" ) func sum(a ...int) int { defer trace(" ...

  6. Nodejs解析HTML网页模块 jsdom

    工作需要抓取某些网页,所以今天试用下了node下的jsdom模块.同样功能的还有jquery jsdom https://npmjs.org/package/jsdom API很简单. jsdom.e ...

  7. asp.net textbox keyup事件触发后台的textchange事件

    textbox文本框text_change事件,失去焦点才会执行. 通过keyup事件,js控制失去焦点. <asp:TextBox runat="server" ID=&q ...

  8. C# Attribute(特性)之---数据契约 [DataContract]

    服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送,如下所 ...

  9. 如何为你的美术妹子做Unity的小工具(三)

    绘制脚本组件监视面板的内容 我们写了一个脚本Test using UnityEngine; using System.Collections; using System.Collections.Gen ...

  10. socket(套接字)

    客户端: 创建套接字(socket) 连接服务器(connect) 通信(send,recv或者write,read) 关闭套接字(closesocket) 示例代码: int main(int ar ...