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. angularJS新增 品优购新增品牌

    前台代码 brand.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...

  2. CCPC-Winter Camp div2 day8 A

    ---恢复内容开始--- 题目: 题解: 我们考虑第i个叶子节点的情况,根据题目给的输入条件,我们可以知道,深度大的节点的序号一定是大于深度浅的节点的序号的 如图 题目要求我们找出每一个叶子节点距离编 ...

  3. Webservice与CXF框架快速入门

    1. Webservice Webservice是一套远程调用技术规范 远程调用RPC, 实现了系统与系统进程间的远程通信.java领域有很多可实现远程通讯的技术,如:RMI(Socket + 序列化 ...

  4. 关于微信内置浏览器安卓端session丢失问题

    项目上线测试,发现微信安卓端存在用户登录无法验证session情况, 导致每次接口请求都无法识别,而苹果客户端不会出现此问题,非微信环境打开不会出现此问题,找到一些解决方案做下记录: 方案1: 由于微 ...

  5. [LeetCode] 14. Longest Common Prefix ☆

    Write a function to find the longest common prefix string amongst an array of strings. 解法: 广度优先搜索:先比 ...

  6. Web Service快速入门

    一言以蔽之:WebService是一种跨编程语言和跨操作系统平台的远程调用技术. 那么它是如何做到这种跨语言,跨平台之间的调用呢? 其实它是以一个xml文件以及webservice这种服务来实现跨平台 ...

  7. elasticsearch 创建索引,以及检索一条数据

    elasticsearch的重要概念 我们可以把elasticsearch当做数据库来理解: index:索引库名称,相当于关系型数据库中的表名,一个elasticsearch集群中可以有多个索引库. ...

  8. 启动hbase输出ignoring option PermSize=128m; support was removed in 8.0告警信息

    ./start-hbase.sh starting master, logging to /home/hadoop/hbase-1.2.4/bin/../logs/hbase-hadoop-maste ...

  9. 汕头市队赛 SRM19 字符题

    从天上掉下来了个这样的问题: 有一个字符串 从中选出两个子串 A,B,求 A+B可以构成的不同串的个数. 还想知道,这么多个串中字典序最大的那一个. 某人捡到了这个问题,并把它扔给了你. [输入] 一 ...

  10. 【vijos】P1066 弱弱的战壕

    [算法]线段树 [题解]将所有坐标按x(第一)和y(第二)从小到大排序,再按顺序插入线段树,即在线段树中将y坐标位置+1,这样就能保证每个坐标能包含的点一定先被处理了,每次询问查询1...a[i].y ...