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 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #include<queue>
 25 #define LL long long
 26 #define maxn 512*65
 27 using namespace std;
 28 int hs[515];
 29 struct Trie
 30 {
 31     int next[maxn][256],fail[maxn],end[maxn];
 32     int root, L;
 33     int newnode()
 34     {
 35         memset(next[L],-1,sizeof(next[L]));
 36         end[L++] = 0 ;
 37         return L-1;
 38     }
 39     void init()
 40     {
 41         L = 0 ;
 42         root = newnode();
 43     }
 44     void insert(int buf[],int len,int K)
 45     {
 46         int now = root;
 47         for(int i = 0 ;i < len ;i ++)
 48         {
 49             if(next[now][buf[i]] ==  -1)
 50             {
 51                 next[now][buf[i]] = newnode();
 52             }
 53             now = next[now][buf[i]];
 54         }
 55         end[now] = K;
 56     }
 57     void build()
 58     {
 59         queue<int> Q;
 60         fail[root] = root;
 61         for(int i = 0;i < 256;i ++)
 62         {
 63             if(next[root][i] == -1)
 64             {
 65                 next[root][i] = root;  //指向root 是没有问题的,我们主要是通过end 数组对个数进行计数的。
 66             }else{
 67                 fail[next[root][i]] = root;
 68                 Q.push(next[root][i]);
 69             }
 70         }
 71         while(!Q.empty())
 72         {
 73             int now = Q.front();
 74             Q.pop();
 75             for(int i = 0 ;i < 256;i ++)
 76             {
 77                 if(next[now][i] == -1)
 78                     next[now][i] =  next[fail[now]][i];
 79                 else{
 80                     fail[next[now][i]] = next[fail[now]][i];
 81                     Q.push(next[now][i]);
 82                 }
 83             }
 84         }
 85     }
 86     void query(int buf[],int len)
 87     {
 88         int now = root ;
 89         for(int  i = 0 ;i < len;i ++)
 90         {
 91             now = next[now][buf[i]];
 92             int temp = now ;
 93             while(temp != root)
 94             {
 95                 if(end[temp])
 96                 {
 97                     hs[end[temp]] = 1;
 98                 }
 99                 temp = fail[temp];
100             }
101         }
102     }
103 };
104 char buf[3058];
105 int  temp[3058];
106 Trie ac;
107 int cbit(char c)
108 {
109     if(c >= ‘A‘ && c <= ‘Z‘)
110         return c -‘A‘;
111     if(c >= ‘a‘ && c <= ‘z‘)
112         return c -‘a‘ + 26;
113     if(c >= ‘0‘ && c <= ‘z‘)
114         return c -‘0‘ + 52;
115     if(c == ‘+‘)
116         return 62;
117     else if(c == ‘/‘)return 63;
118 }
119 void debug(int x)
120 {
121     printf("%d\n",x);
122     for(int  i = 0 ;i < x; i ++)
123         printf("%c",temp[i]);
124     printf("\n");
125 }
126 int lt = 0;
127 void change(){
128
129     int len = strlen(buf);
130     int t = 0;
131     int ln = 0 ;
132     int tt;
133     lt = 0;
134     for(int i = 0 ;i < len;i ++)
135     {
136         if(buf[i] != ‘=‘)
137         {
138             if(buf[i] >= ‘A‘ && buf[i] <= ‘Z‘)
139                 tt =  buf[i] -‘A‘;
140             else if(buf[i] >= ‘a‘ && buf[i] <= ‘z‘)
141                 tt = buf[i]-‘a‘ + 26;
142             else if(buf[i] >= ‘0‘ && buf[i] <= ‘z‘)
143                 tt= buf[i] -‘0‘ + 52;
144             else if(buf[i] == ‘+‘)
145                 tt = 62;
146             else if(buf[i] == ‘/‘)tt = 63;
147             if(6 < 8 - t)
148             {
149                 ln += (tt << (8-t-6));
150                 t += 6;
151             }else{
152                 ln += (tt >> (6-8+t));
153                 temp[lt++] = ln;
154                 ln = (tt&((1<<(6-8+t)) -1)) << (8-(6-8+t));
155                 t = (6-8+t);
156             }
157         }
158     }
159     //printf("%d %d\n",lt,rlen);
160 }
161
162 int main(){
163     int n;
164     while(scanf("%d",&n) != EOF)
165     {
166         ac.init();
167         for(int i =1 ;i <= n;i ++)
168         {
169             scanf("%s",buf);
170             change();
171             ac.insert(temp,lt,i);
172             // debug(lt);
173         }
174         ac.build();
175         int m;
176         scanf("%d",&m);
177         for(int i = 1;i <= m;i ++)
178         {
179             memset(hs,0,sizeof(hs));
180             scanf("%s",buf);
181             change();
182             // debug(lt);
183             int ans = 0;
184             ac.query(temp,lt);
185             for(int i = 1;i <= n;i ++)
186                 if(hs[i])
187                 {
188                     ans ++ ;
189                 }
190             printf("%d\n",ans);
191         }
192         printf("\n");
193     }
194     return 0;
195 }

时间: 2024-10-11 21:34:09

ZOJ3430 Detect the Virus AC自动机的相关文章

zoj 3430 Detect the Virus(AC自动机)

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

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

AC自动机

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

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 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

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