zoukankan      html  css  js  c++  java
  • ZOJ 3430 Detect the Virus(AC自动机)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430

    题意:给你n个编码后的模式串,和m个编码后的主串,求原来主串中含有模式串的个数

    思路:首先要将模式串解码成未编码前来建立ac自动机,然后解码主串扫描统计即可。

    code:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #include <set>
      5 using namespace std;
      6 const int KIND = 256;
      7 const int MAXN = 32800;
      8 
      9 struct Trie
     10 {
     11     int next[MAXN][KIND], fail[MAXN], id[MAXN];
     12     int root, L, num;
     13     int create()
     14     {
     15         for (int i = 0; i < KIND; ++i)
     16             next[L][i] = -1;
     17         return L++;
     18     }
     19     void init()
     20     {
     21         L = 0;
     22         num = 0;
     23         memset(id, 0, sizeof(id));
     24         root = create();
     25     }
     26     void insert(unsigned char str[], int len)
     27     {
     28         int now = root;
     29         for (int i = 0; i < len; ++i)
     30         {
     31             if (-1 == next[now][str[i]])
     32                 next[now][str[i]] = create();
     33             now = next[now][str[i]];
     34         }
     35         id[now] = ++num;
     36     }
     37     void build()
     38     {
     39         queue<int>Q;
     40         fail[root] = root;
     41         for (int i = 0; i < KIND; ++i)
     42         {
     43             if (-1 == next[root][i])
     44                 next[root][i] = root;
     45             else
     46             {
     47                 fail[next[root][i]] = root;
     48                 Q.push(next[root][i]);
     49             }
     50         }
     51         while (!Q.empty())
     52         {
     53             int now = Q.front();
     54             Q.pop();
     55             for (int i = 0; i < KIND; ++i)
     56             {
     57                 if (-1 == next[now][i])
     58                     next[now][i] = next[fail[now]][i];
     59                 else
     60                 {
     61                     fail[next[now][i]] = next[fail[now]][i];
     62                     Q.push(next[now][i]);
     63                 }
     64             }
     65         }
     66     }
     67     int query(unsigned char str[], int len)
     68     {
     69         set<int>S;
     70         int now = root;
     71         for (int i = 0; i < len; ++i)
     72         {
     73             now = next[now][str[i]];
     74             int temp = now;
     75             while (temp != root)
     76             {
     77                 if (id[temp]) S.insert(id[temp]);
     78                 temp = fail[temp];
     79             }
     80         }
     81         return (int)S.size();
     82     }
     83 };
     84 
     85 Trie ac;
     86 char buf[4000];
     87 unsigned char temp[4000];
     88 unsigned char str[2500];
     89 
     90 unsigned char Tran(char ch)
     91 {
     92     if (ch >= 'A' && ch <= 'Z') return ch - 'A';
     93     if (ch >= 'a' && ch <= 'z') return ch - 'a' + 26;
     94     if (ch >= '0' && ch <= '9') return ch - '0' + 52;
     95     if (ch == '+') return 62;
     96     return 63;
     97 }
     98 
     99 int Decode(int len)
    100 {
    101     int k = 0;
    102     for (int i = 0; i < len; i += 4)
    103     {
    104         str[k++] = (temp[i]<<2)|(temp[i + 1]>>4);
    105         if (i + 2 < len) str[k++] = (temp[i + 1]<<4)|(temp[i + 2]>>2);
    106         if (i + 3 < len) str[k++] = (temp[i + 2]<<6)|(temp[i + 3]);
    107     }
    108     return k;
    109 }
    110 
    111 int main()
    112 {
    113     int n, m;
    114     while (scanf("%d", &n) != EOF)
    115     {
    116         ac.init();
    117         for (int i = 0; i <n; ++i)
    118         {
    119             scanf("%s", buf);
    120             int len = strlen(buf);
    121             while ('=' == buf[len - 1]) --len;
    122             for (int j = 0; j < len; ++j) temp[j] = Tran(buf[j]);
    123             ac.insert(str, Decode(len));
    124         }
    125         ac.build();
    126         scanf("%d", &m);
    127         for (int i = 0; i < m; ++i)
    128         {
    129             scanf("%s", buf);
    130             int len = strlen(buf);
    131             while ('=' == buf[len - 1]) --len;
    132             for (int j = 0; j < len; ++j) temp[j] = Tran(buf[j]);
    133             printf("%d
    ", ac.query(str, Decode(len)));
    134         }
    135         printf("
    ");
    136     }
    137     return 0;
    138 }
  • 相关阅读:
    日记 2018/1/12
    【程序员笔试面试必会——排序①】Python实现 冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序
    Python笔试、面试 【必看】
    高性能Go并发
    Go连接MySql数据库Error 1040: Too many connections错误解决
    MAC 配置文件 ~/.zshrc
    go-statsd项目
    日记 2017.11.20
    sed 命令详解
    Opentsdb简介(一)
  • 原文地址:https://www.cnblogs.com/ykzou/p/4598077.html
Copyright © 2011-2022 走看看