题目大意:给你一些病毒的特征码,然后再给一些文本,判断每个文本有多少种病毒,不过给的字符串都是加密处理过的,给的每个字符串都有对应一个64以内的一个数(题目里面那个表就是),然后可以把这个64以内的这个数化成6位的二进制数,然后把这些二进制数每8位再化成一个字符,这就是原来的字符,比如 QA== ->编号0 1->二进制010000 000000->每8位变成一个字符 01000000 0000(后面这4个0就是那两个==,可以舍去)-> 64('@')。
 
分析:因为是化成8位的二进制,2^8 = 256,不过因为有‘\0’这样的字符,所以无法使用char来搞,开一个int数组是个不错的选择,当然也得注意内存开销,申请内存的方式会MLE,实验得出结果开6W最好.....真是让人感觉很恶心,错了19次!!
 
代码如下:
===============================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std; const int MAXN = ;
const int MAXM = ;///2^8
const int oo = 1e9+; const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int virus[MAXN], MumStr[MAXN];
char s[MAXN];
int password[MAXN*]; struct node
{
int Fail, next[MAXM];
int leaf, num; void InIt()
{
Fail = leaf = num = ;
memset(next, , sizeof(next));
} }trie[];
int top; int TurnStr(char s[], int p[])
{
int i, j, k=; for(i=; s[i] && s[i] != '='; i++)
{
s[i] = strchr(cb64, s[i]) - cb64; for(j=; j>=; j--)
{
password[k+j] = s[i] % ;
s[i] /= ;
} k += ;
} int len = ; for(i=j=; i<k; i++)
{
j = j* + password[i]; if((i+) % == )
{
p[len++] = j;
j = ;
}
} return len;
}
void Insert(int root, int N)
{
int p = root; for(int i=; i<N; i++)
{
int k = virus[i]; if(trie[p].next[k] == )
{
trie[p].next[k] = ++top;
trie[top].InIt();
}
p = trie[p].next[k];
} trie[p].leaf += ;
}
void GetFail(int root)
{
int p = root, temp;
queue<int> Q; trie[root].Fail = -; for(int i=; 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=; i<MAXM; i++)if(trie[p].next[i])
{
int k = trie[p].next[i];
temp = trie[p].Fail; while(temp != -)
{
if(trie[temp].next[i])
{
trie[k].Fail = trie[temp].next[i];
break;
} temp = trie[temp].Fail;
} if(temp == -)
trie[k].Fail = root; Q.push(k);
}
}
}
int Query(int root, int N, int num)
{
int sum = ;
int p = root, temp; for(int i=; 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 += ;
trie[temp].num = num;
temp = trie[temp].Fail;
}
} return sum;
} int main()
{
int N, M; while(scanf("%d", &N) != EOF)
{
int root = ; trie[].InIt();
top = ; for(int i=; i<=N; i++)
{
scanf("%s", s);
int len = TurnStr(s, virus); Insert(root, len);
} GetFail(root);
scanf("%d", &M); for(int i=; i<=M; i++)
{
scanf("%s", s);
int len = TurnStr(s, MumStr); printf("%d\n", Query(root, len, i));
}
printf("\n");
} return ;
}

 

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

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

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

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

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

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

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

  4. ZOJ 3430 Detect the Virus

    传送门: Detect the Virus                                                                                ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. SQL Server中的死锁

    简介 死锁的本质是一种僵持状态,是多个主体对于资源的争用而导致的.理解死锁首先需要对死锁所涉及的相关观念有一个理解. 一些基础知识 要理解SQL Server中的死锁,更好的方式是通过类比从更大的面理 ...

  2. Android布局管理器(线性布局)

    线性布局有LinearLayout类来代表,Android的线性布局和Swing的Box有点相似(他们都会将容器里面的组件一个接一个的排列起来),LinearLayout中,使用android:ori ...

  3. Orace数据库锁表的处理与总结<摘抄与总结三>

    当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误. TX锁等待的分析 Oracle数据库中一般使用行级锁. 当Oracle ...

  4. Spring 创建bean的模式

    在默认情况下,spring创建bean是单例模式 scope="singleton ",还有一种方式为多例模式[prototype]     scope          sing ...

  5. java常用指令

    javac 编译java源文件到字节码文件 -d XXX 1.指定编译后的字节码文件存放位置. 2.若编译的java源文件中使用包名,则根据包名生成相应的子目录 javac -d . Hello.ja ...

  6. alsa utils工具使用

    1.amixer用于控制设置 amixer [-c card] [cmd] ./amixer contents ./amixer cset ./amixer cget 2. aplay ./aplay ...

  7. NewRowNeeded和UserAddedRow事件以及RowsAdded的区别使用

    NewRowNeeded事件当 VirtualMode 属性为 true 时,将在用户定位到 DataGridView 底部的新行时发生,适合给新行建立一些默认数据和按规则应该产生的数据,但此时不推荐 ...

  8. mvc的真实含义

    MVC是一个设计模式,它强制性的使应用程序的输入.处理和输出分开.使用 MVC应用程序被分成三个核心部件:模型(M).视图(V).控制器(C),它们各自处理自己的任务. 视图 : 视图是用户看到并与之 ...

  9. sphinx ---rotate 运行机制

    如果sphinx在运行中,要indexer时,需要加上--rotate参数,这样索引完就直接生效了. 原因是sphinx的searchd在启动时会创建一个 .spl 锁文件,并在关闭时会删除它.在in ...

  10. python模块之paramiko

              46.python模块之paramiko   SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: 1 2 3 4 5 6 7 8 9 10 11 12 13 ...