zoj3430Detect the Virus(ac自动机)

链接

解码之后是跟普通的自动机求解一下的,只不过解码比较恶心,512=》N》=0 ,所以不能用字符串来存,需要转换成整数来做。

  1 #include <iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<stdlib.h>
6 #include<vector>
7 #include<cmath>
8 #include<queue>
9 #include<set>
10 using namespace std;
11 #define N 53769
12 #define NN 15010
13 #define LL long long
14 #define INF 0xfffffff
15 const double eps = 1e-8;
16 const double pi = acos(-1.0);
17 const double inf = ~0u>>2;
18 const int child_num = 258;
19 char s[NN],vir[NN];
20 int di[NN*8],od[NN],vv[NN];
21 bool f[N];
22 class ACAutomation
23 {
24 private:
25 int ch[N][child_num];
26 int val[N];
27 int fail[N];
28 int Q[N];
29 int id[258];
30 int sz;
31 // int dp[2][N][1<<10];
32 public:
33 void init()
34 {
35 fail[0] = 0;
36 for(int i = 0 ; i < child_num; i++)
37 id[i] = i;
38 }
39 void reset()//初始化
40 {
41 memset(ch[0],0,sizeof(ch[0]));
42 memset(val,0,sizeof(val));
43 sz = 1;
44 }
45 void insert(int *a,int key,int k)//建立trie树
46 {
47 int p = 0;
48 for( int i = 0; i < k ; i++)
49 {
50 int c = id[a[i]];
51 if(ch[p][c]==0)
52 {
53 memset(ch[sz],0,sizeof(ch[sz]));
54 ch[p][c] = sz++;
55 }
56 p = ch[p][c];

57 }
58 val[p] += key;
59 }
60 void construct()//构建fail指针
61 {
62 int head = 0,tail = 0,i;
63 for(i = 0 ;i < child_num ; i++)
64 {
65 if(ch[0][i])
66 {
67 fail[ch[0][i]] = 0;
68 Q[tail++] = ch[0][i];
69 }
70 }
71 while(head!=tail)
72 {
73 int u = Q[head++];
74 for(i = 0 ;i < child_num ;i ++)
75 {
76 if(ch[u][i]!=0)
77 {
78 Q[tail++] = ch[u][i];
79 fail[ch[u][i]] = ch[fail[u]][i];
80 }
81 else
82 ch[u][i] = ch[fail[u]][i];
83 }
84 }
85 }
86 int work(int *s,int k)
87 {
88 int p = 0,ans = 0;
89 memset(f,0,sizeof(f));
90 for(int i = 0; i < k ; i++)
91 {
92 int d = id[s[i]];
93 p = ch[p][d];
94 int tmp = p;
95 while(tmp!=0&&!f[tmp])
96 {
97 ans+=val[tmp];
98 f[tmp] = 1;
99 tmp = fail[tmp];
100 }
101 }
102 return ans;
103 }
104 }ac;
105 int change(char *a)
106 {
107 int i,k = strlen(a),j;
108 int g = 0,gg,num =0 ;
109 for(i = 0;i < k ; i++)
110 {
111 if(a[i]==‘=‘)
112 {
113 num++;
114 continue;
115 }
116 int x = od[a[i]];gg=0;
117 for(j=5;j>=0;j--)
118 {
119 di[g++]=((x&(1<<j))>0);
120 }
121 }
122 if(num==1)
123 g-=2;
124 else if(num==2)
125 g-=4;
126 gg = 0;
127 int y = 0;
128 for(j = 0 ;j < g ; j++)
129 {
130 y+=di[j]*(1<<(7-j%8));
131 if((j+1)%8==0)
132 {
133 vv[gg++] = y;
134 y = 0;
135 }
136 }
137 return g/8;
138 }
139 int main()
140 {
141 int n,i,m;
142 for(i = ‘A‘ ; i <= ‘Z‘ ; i++)
143 od[i] = i-‘A‘;
144 for(i = ‘a‘ ; i <= ‘z‘ ; i++)
145 od[i] = 26+i-‘a‘;
146 for(i = ‘0‘; i <= ‘9‘ ; i++)
147 od[i] = 52+i-‘0‘;
148 od[‘+‘] = 62,od[‘/‘] = 63;
149 ac.init();
150 while(scanf("%d",&n)!=EOF)
151 {
152 ac.reset();
153 for(i = 1; i <= n; i++)
154 {
155 scanf("%s",vir);
156 int len = change(vir);
157 ac.insert(vv,1,len);
158 }
159 ac.construct();
160 scanf("%d",&m);
161 for(i = 1; i <= m ;i++)
162 {
163 scanf("%s",s);
164 int len = change(s);
165 printf("%d\n",ac.work(vv,len));
166 }
167 puts("");
168 }
169 return 0;
170 }

zoj3430Detect the Virus(ac自动机)

时间: 2024-10-20 21:02:36

zoj3430Detect the Virus(ac自动机)的相关文章

ZOJ3430 Detect the Virus AC自动机

题意:给你base64编码后的模式串和文本串,让你看编码之前的文本串和分别包含了多少模式串 解题思路:主要是编码还有注意分支要开256 ,然后就是裸的AC自动机 解题代码: 1 // File Name: temp.cpp 2 // Author: darkdream 3 // Created Time: 2014年09月11日 星期四 15时18分256秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8

zoj 3430 Detect the Virus(AC自动机)

题目连接:zoj 3430 Detect the Virus 题目大意:给定一个编码完的串,将每一个字符对应着表的数值转换成6位二进制,然后以8为一个数值,重新形成字符 串,判断给定询问串是否含有字符集中的串. 解题思路:主要是题意,逆编码部分注意,转换完了之后,可能有字符'\0',所以不能用字符串的形式储存,要用int型 的数组.注意有相同串的可能. #include <cstdio> #include <cstring> #include <queue> #incl

AC自动机

AC自动机 直接学AC自动机比较难理解,强烈建议先学完KMP和字典树并进行一定的练习后,对于失配指针和字典树构造有一定理解后再来学AC自动机的内容.有关AC自动机的详细介绍可见刘汝佳的<算法竞赛入门经典训练指南>P214. 给你一个字典(包含n个不重复的单词),然后给你一串连续的字符串文本(长为len),问你该文本里面的哪些位置正好出现了字典中的某一个或某几个单词?输出这些位置以及出现的单词. 这个问题可以用n个单词的n次KMP算法来做(效率为O(n*len*单词平均长度)),也可以用1个字典

hdu 3695 10 福州 现场 F - Computer Virus on Planet Pandora 暴力 ac自动机

F - Computer Virus on Planet Pandora Time Limit:2000MS     Memory Limit:128000KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 3695 Appoint description:  System Crawler  (2014-11-05) Description Aliens on planet Pandora also write comp

zoj 3430 Detect the Virus(AC自动机)

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

ZOJ 3430 Detect the Virus (AC自动机)

题目链接:Detect the Virus 题意:n个模式串,一个文本串,问文本串包含几个模式串. 解析:解码 + AC自动机. 解码过程:先将字符串转换成ASCII 然后根据相应的ASCII 转换成二进制,每一个是6位,不够加0,然后取8位为一个字符,求得的字符串为要的字符串. PS:注意sigma_size = 256 AC代码: #include <bits/stdc++.h> using namespace std; struct Trie{ int next[520*64][256]

hdu 3695:Computer Virus on Planet Pandora(AC自动机,入门题)

Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 256000/128000 K (Java/Others)Total Submission(s): 2578    Accepted Submission(s): 713 Problem Description Aliens on planet Pandora also write computer programs l

HDU 3695 Computer Virus on Planet Pandora (AC自动机)

题意:有n种病毒序列(字符串),一个模式串,问这个字符串包含几种病毒. 包含相反的病毒也算,字符串中[qx]表示有q个x字符.详细见案列. 0 < q <= 5,000,000尽然不会超,无解 3 2 AB DCB DACB 3 ABC CDE GHI ABCCDEFIHG 4 ABB ACDEE BBB FEEE A[2B]CD[4E]F Sample Output 0 3 2 Hint In the second case in the sample input, the reverse

[AC自动机]HDOJ3695 Computer Virus on Planet Pandora

题意:给t.n,t个案例,n个字符串 下面给n+1个字符串,n个互不相同的小串,最后一个是模式串 模式串会出现[qx]的形式,q为数字,x为一个字母 问n个小串在模式串中出现的个数,正着出现.反着出现都算. 蛮裸的ac自动机,本来想着在query里面把找到过的end清零,把模式串展开正着反着找两遍,那即使再找到加零也不影响.但是超时了... 于是把找到过的end标为-1,-1了就不再找下去,就可以了~上代码 #include <cstdio> #include <cstdlib>