Detect the Virus - ZOJ 3430(恶心的自动机)
2015-08-23 10:11
211 查看
题目大意:给你一些病毒的特征码,然后再给一些文本,判断每个文本有多少种病毒,不过给的字符串都是加密处理过的,给的每个字符串都有对应一个64以内的一个数(题目里面那个表就是),然后可以把这个64以内的这个数化成6位的二进制数,然后把这些二进制数每8位再化成一个字符,这就是原来的字符,比如 QA== ->编号0 1->二进制010000 000000->每8位变成一个字符 01000000 0000(后面这4个0就是那两个==,可以舍去)-> 64('@')。
[b]分析:因为是化成8位的二进制,2^8 = 256,不过因为有‘\0’这样的字符,所以无法使用char来搞,开一个int数组是个不错的选择,当然也得注意内存开销,申请内存的方式会MLE,实验得出结果开6W最好.....真是让人感觉很恶心,错了19次!![/b]
[b]代码如下:[/b]
[b]===============================================================================================================================[/b]
[b]分析:因为是化成8位的二进制,2^8 = 256,不过因为有‘\0’这样的字符,所以无法使用char来搞,开一个int数组是个不错的选择,当然也得注意内存开销,申请内存的方式会MLE,实验得出结果开6W最好.....真是让人感觉很恶心,错了19次!![/b]
[b]代码如下:[/b]
[b]===============================================================================================================================[/b]
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int MAXN = 10007; const int MAXM = 256;///2^8 const int oo = 1e9+37; const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int virus[MAXN], MumStr[MAXN]; char s[MAXN]; int password[MAXN*8]; struct node { int Fail, next[MAXM]; int leaf, num; void InIt() { Fail = leaf = num = 0; memset(next, 0, sizeof(next)); } }trie[60000]; int top; int TurnStr(char s[], int p[]) { int i, j, k=0; for(i=0; s[i] && s[i] != '='; i++) { s[i] = strchr(cb64, s[i]) - cb64; for(j=5; j>=0; j--) { password[k+j] = s[i] % 2; s[i] /= 2; } k += 6; } int len = 0; for(i=j=0; i<k; i++) { j = j*2 + password[i]; if((i+1) % 8 == 0) { p[len++] = j; j = 0; } } return len; } void Insert(int root, int N) { int p = root; for(int i=0; i<N; i++) { int k = virus[i]; if(trie[p].next[k] == 0) { trie[p].next[k] = ++top; trie[top].InIt(); } p = trie[p].next[k]; } trie[p].leaf += 1; } void GetFail(int root) { int p = root, temp; queue<int> Q; trie[root].Fail = -1; for(int i=0; i<MAXM; i++)if(trie[p].next[i]) { int k = trie[p].next[i]; trie[k].Fail = root; Q.push(k); } while(Q.size()) { p = Q.front(); Q.pop(); for(int i=0; i<MAXM; i++)if(trie[p].next[i]) { int k = trie[p].next[i]; temp = trie[p].Fail; while(temp != -1) { if(trie[temp].next[i]) { trie[k].Fail = trie[temp].next[i]; break; } temp = trie[temp].Fail; } if(temp == -1) trie[k].Fail = root; Q.push(k); } } } int Query(int root, int N, int num) { int sum = 0; int p = root, temp; for(int i=0; i<N; i++) { int k = MumStr[i]; while(!trie[p].next[k] && p!=root) p = trie[p].Fail; if(!trie[p].next[k])continue; temp = p = trie[p].next[k]; while(temp != root && trie[temp].num != num) { if(trie[temp].leaf) sum += 1; trie[temp].num = num; temp = trie[temp].Fail; } } return sum; } int main() { int N, M; while(scanf("%d", &N) != EOF) { int root = 0; trie[0].InIt(); top = 0; for(int i=1; i<=N; i++) { scanf("%s", s); int len = TurnStr(s, virus); Insert(root, len); } GetFail(root); scanf("%d", &M); for(int i=1; i<=M; i++) { scanf("%s", s); int len = TurnStr(s, MumStr); printf("%d\n", Query(root, len, i)); } printf("\n"); } return 0; }
相关文章推荐
- addChildViewController的用法
- 常用的日文正文字体有哪些?
- ASP.NET MVC 4 插件化架构简单实现-思路篇
- 每个Android开发者应该知道的6个SDK和API
- 《JavaScript高级程序设计》
- 洛谷1908 逆序对 解题报告
- jquery ajax 如何向jsp提交表单数据
- hdu 5418 Victor and World(floyd+状压dp)
- 黑马程序员-[OC]学习之旅-ARC机制和类别
- Ubuntu 安装keepalived
- UILable
- 我的职业规划(android)
- Java之旅hibernate(2)——目录结构
- hdu1114(完全背包)
- 详解Hibernate Session & Transaction
- 【java基础学习-2--】关于Hashcode()的使用
- FATAL ERROR in native method: JDWP No transports initialized, jvmtiError=AGENT_ERROR_TRANSPORT_INIT
- struts 2 标签 总结
- ASP.NET MVC 4 插件化架构简单实现-思路篇
- 20多个常用的免费WebService接口