Detect the Virus 


Time Limit: 2 Seconds      Memory Limit: 65536 KB

One day, Nobita found that his computer is extremely slow. After several hours' work, he finally found that it was a virus that made his poor computer slow and the virus was activated by a misoperation of opening an attachment of an email.

Nobita did use an outstanding anti-virus software, however, for some strange reason, this software did not check email attachments. Now Nobita decide to detect viruses in emails by himself.

To detect an virus, a virus sample (several binary bytes) is needed. If these binary bytes can be found in the email attachment (binary data), then the attachment contains the virus.

Note that attachments (binary data) in emails are usually encoded in base64. To encode a binary stream in base64, first write the binary stream into bits. Then take 6 bits from the stream in turn, encode these 6 bits into a base64 character according the following table:

That is, translate every 3 bytes into 4 base64 characters. If the original binary stream contains 3k + 1 bytes, where k is an integer, fill last bits using zero when encoding and append '==' as padding. If the original binary stream contains 3k + 2 bytes, fill last bits using zero when encoding and append '=' as padding. No padding is needed when the original binary stream contains 3k bytes.

Value 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Encoding A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f
Value 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
Encoding g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /

For example, to encode 'hello' into base64, first write 'hello' as binary bits, that is: 01101000 01100101 01101100 01101100 01101111
Then, take 6 bits in turn and fill last bits as zero as padding (zero padding bits are marked in bold): 011010 000110 010101 101100 011011 000110 111100
They are 26 6 21 44 27 6 60 in decimal. Look up the table above and use corresponding characters: aGVsbG8
Since original binary data contains 1 * 3 + 2 bytes, padding is needed, append '=' and 'hello' is finally encoded in base64: aGVsbG8=

Section 5.2 of RFC 1521 describes how to encode a binary stream in base64 much more detailedly:

Click here to see Section 5.2 of RFC 1521 if you have interest

Here is a piece of ANSI C code that can encode binary data in base64. It contains a function, encode (infile, outfile), to encode binary file infile in base64 and output result to outfile.

Click here to see the reference C code if you have interest

Input

Input contains multiple cases (about 15, of which most are small ones). The first line of each case contains an integer N (0 <= N <= 512). In the next N distinct lines, each line contains a sample of a kind of virus, which is not empty, has not more than 64 bytes in binary and is encoded in base64. Then, the next line contains an integer M (1 <= M <= 128). In the following M lines, each line contains the content of a file to be detected, which is not empty, has no more than 2048 bytes in binary and is encoded in base64.

There is a blank line after each case.

Output

For each case, output M lines. The ith line contains the number of kinds of virus detected in the ith file.

Output a blank line after each case.

Sample Input

3
YmFzZTY0
dmlydXM=
dDog
1
dGVzdDogdmlydXMu 1
QA==
2
QA==
ICAgICAgICA=

Sample Output

2

1
0

Hint

In the first sample case, there are three virus samples: base64, virus and t: , the data to be checked is test: virus., which contains the second and the third, two virus samples.

/**
题意:给你n个模版,然后再给出一个字符串,问该字符串包含几个模版
做法:AC自动机 字符串的转换有些麻烦,先将字符串转换成ASCII 然后根据相应的ASCII 转换成二进制,每一个是6位,不够加0,然后取8位为一个字符,求得的字符串为要的字符串
**/
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#define maxn 520*64
using namespace std;
int n;
int tot = ;
unsigned char ch1[maxn];
struct Tire
{
int next[maxn][],end[maxn],fail[maxn];
int root,L;
int newnode()
{
for(int i = ;i < ;i++)
next[L][i] = -;
end[L++] = -;
return L-;
}
void init()
{
L = ;
root = newnode();
}
void insert(unsigned char buf[],int len,int id)
{
int now = root;
for(int i = ;i < len;i++)
{
if(next[now][buf[i]] == -)
next[now][buf[i]] = newnode();
now = next[now][buf[i]];
}
end[now] = id;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ;i < ;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 < ;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]);
}
}
}
bool used[];
int query(unsigned char buf[],int len)
{
memset(used,false,sizeof(used));
int now = root;
for(int i = ;i < len;i++)
{
now = next[now][buf[i]];
int temp = now;
while( temp!=root )
{
if(end[temp] != -)
used[end[temp]]=true;
temp = fail[temp];
}
}
int res = ;
for(int i = ;i < n;i++)
if(used[i])
res++;
return res;
}
};
unsigned char Get(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 ;
else return ;
} void solve(char ch[],int len)
{
string str;
string str1;
str1 = "";
for(int i=; i<len; i++)
{
str = "";
int res = int(ch[i]);
while(res)
{
str += res% + '';
res /= ;
}
while(str.length() != ) str += "";
reverse(str.begin(),str.end());
str1 += str;
}
int len1 = str1.length();
while(len1% !=) len1--;
int mm = ;
memset(ch1,'\0',sizeof(ch1));
for(int i=; i<len1; i+=)
{
int res = ;
for(int j=; j<; j++)
{
res += (str1[i+j] -'') * pow(2.0,-j);
}
ch1[mm++] = char(res);
}
//cout<<ch1<<"\n";
tot = mm;
return ;
} Tire ac;
char buf[maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int m;
while(~scanf("%d",&n))
{
ac.init();
char xx[maxn];
for(int i=; i<n; i++)
{
memset(xx,'\0',sizeof(xx));
scanf("%s",buf);
int len = strlen(buf);
while(buf[len-]=='=')len--;
for(int j=; j<len; j++)
{
xx[j] = Get(buf[j]);
}
solve(xx,len);
ac.insert(ch1,tot,i);
}
ac.build();
scanf("%d",&m);
while(m--)
{
scanf("%s",buf);
int len = strlen(buf);
memset(xx,'\0',sizeof(xx));
while(buf[len-] == '=')
{
--len;
}
for(int j=; j<len; j++)
{
xx[j] = Get(buf[j]);
}
solve(xx,len);
printf("%d\n",ac.query(ch1,tot));
}
printf("\n");
}
return ;
}

ZOJ-3430的更多相关文章

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

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

  2. HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)

    最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...

  3. Detect the Virus ZOJ - 3430 AC自动机

    One day, Nobita found that his computer is extremely slow. After several hours' work, he finally fou ...

  4. ZOJ 3430 Detect the Virus

    传送门: Detect the Virus                                                                                ...

  5. ZOJ 3430 Detect the Virus(AC自动机)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430 题意:给你n个编码后的模式串,和m个编码后的主串,求原来主 ...

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

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

  7. Detect the Virus - ZOJ 3430(恶心的自动机)

    题目大意:给你一些病毒的特征码,然后再给一些文本,判断每个文本有多少种病毒,不过给的字符串都是加密处理过的,给的每个字符串都有对应一个64以内的一个数(题目里面那个表就是),然后可以把这个64以内的这 ...

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

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

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

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

  10. ZOJ - 3430 ac自动机

    这题主要就是解码过程很恶心,不能用char存,一共wa了20发 题意:先给n串加密后的字符,然后m串加密后的字符,解码之后求n对应每个m的匹配数,很显然的ac自动机 加密过程是先用对应ascii表的标 ...

随机推荐

  1. HDU5306:Gorgeous Sequence——题解

    http://acm.hdu.edu.cn/showproblem.php?pid=5306 给一个数组,m次操作: 1:l r x,将a[i](l<=i<=r)=min(a[i],x) ...

  2. Leetcode中单链表题总结

    以下是个人对所做过的LeetCode题中有关链表类型题的总结,博主小白啊,若有错误的地方,请留言指出,谢谢. 一.有关反转链表 反转链表是在单链表题中占很大的比例,有时候,会以各种形式出现在题中,是比 ...

  3. POJ.2142 The Balance (拓展欧几里得)

    POJ.2142 The Balance (拓展欧几里得) 题意分析 现有2种质量为a克与b克的砝码,求最少 分别用多少个(同时总质量也最小)砝码,使得能称出c克的物品. 设两种砝码分别有x个与y个, ...

  4. UVA.122 Trees on the level(二叉树 BFS)

    UVA.122 Trees on the level(二叉树 BFS) 题意分析 给出节点的关系,按照层序遍历一次输出节点的值,若树不完整,则输出not complete 代码总览 #include ...

  5. HDOJ.1263 水果(map)

    水果 点我跳转到题面 点我一起学习STL-MAP 题意分析 给出多组测试数据,每组数据有多条信息.分别是水果种类,地点,和水果数目.每组信息要按照样例输出,并且输出要按照地点->水果种类的字典序 ...

  6. 51nod 1273 旅行计划(思维题)

    一开始看到这题真的有点懵逼...一直在想着套算法,结果题解除了sort和dfs其他什么都没用到 显然每次到达的一定都是叶子,先从根节点dfs一遍,按深度对叶子降序排序,按这个顺序向根节点dfs,路径上 ...

  7. 基于jquery的扩展写法

    (function($){ $.fn.aa = function(canshu){ html = $(this).text(); alert(html) }})(jQuery); (function( ...

  8. Spring源码解析-JdbcTemplate

    JdbcTemplate类图 从类继承关系上来看,JdbcTemplate继承了基类JdbcAccessor和接口类JdbcOperation,在基类JdbcAccessor的设计中,对DataSou ...

  9. Ubuntu 16.04使用python3.x相关

    下载pip3 Python 3.x版本使用pip3,它会把你想下载的包放到usr/local/lib/python3.5/dist-packages/下,而非usr/local/lib/python2 ...

  10. ARM指令集、Thumb指令集、Thumb-2指令集

    MCU使用什么指令集主要由内核决定的,比如Cortex-M3使用的是Thumb-2指令集 ARM指令集: 编代码全部是 32bits 的,每条指令能承载更多的信息,因此使用最少的指令完成功能, 所以在 ...