zoukankan      html  css  js  c++  java
  • ZOJ 3430 Detect the Virus 【AC自动机+解码】

    解码的那些事儿,不多说。

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


    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <string>
    #include <iostream>
    using namespace std;
    vector<int> ans;
    
    struct AC_Automata {
        #define N 60010
        #define M 256
        int ch[N][M], sz;
        int val[N], last[N], f[N], cc[N];
    
        void clear() {
            sz = 1;
            memset(ch[0], 0, sizeof(ch[0]));
        }
    
        void insert(int s[], int l, int v) {
            int u = 0;
            for (int i=0; i<l; i++) {
                int c = s[i];
                if (!ch[u][c]) {
                    memset(ch[sz], 0, sizeof(ch[sz]));
                    val[sz] = 0;
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            val[u] = v;
        }
        void build() {
            queue<int> q;
            f[0] = 0;
            for (int c=0; c<M; c++) {
                int u = ch[0][c];
                if (u) { f[u] = last[u] = 0; q.push(u); }
            }
            while (!q.empty()) {
                int r = q.front(); q.pop();
                for (int c=0; c<M; c++) {
                    int u = ch[r][c];
                    if (!u) { ch[r][c] = ch[f[r]][c]; continue; }
                    q.push(u);
                    f[u] = ch[f[r]][c];
                    last[u] = val[f[u]] ? f[u] : last[f[u]];
                }
            }
        }
        void find(int s[], int l) {
            int j = 0;
            for (int i=0; i<l; i++) {
                int c = s[i];
                j = ch[j][c];
    
                if (val[j]) print(j);
                else if (last[j]) print(last[j]);
            }
        }
        void print(int j) {
            if (j) {
                ans.push_back(val[j]);
                print(last[j]);
            }
        }
    } ac;
    int get(char c) {
        if (c >= 'A' && c <= 'Z') return c-'A';
        if (c >= 'a' && c <= 'z') return c-'a'+26;
        if (c >= '0' && c <= '9') return c-'0'+ 52;
        if (c == '+') return 62;
        return 63;
    }
    
    int ss[30002];
    int bit[30003*10];
    
    int decode(char str[]) {
        int top = 0;
        int a[10];
    
        for(int i=0; str[i]; i++) {
            if(str[i]!='='){
                int x = get(str[i]);
                for(int j=5;j>=0;j--){
                    a[j] = x & 1;
                    x >>= 1;
                }
                for (int j=0; j<6; j++) bit[top++] = a[j];
            }else
                top -= 2;
        }
    
        int x = 0;
        int tot = 0;
        for(int i=0;i<top;){
            x = 0;
            for(int j=0;j<8;j++)
                x = x<<1 | bit[i++];
            ss[tot++] = x;
        }
        return tot;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    
    
        int n, m;
        char s[30023];
    
        while (scanf(" %d", &n) == 1) {
            ac.clear();
            for (int i=1; i<=n; i++) {
                scanf(" %s", s);
                int l = decode(s);
                ac.insert(ss, l, i);
            }
            ac.build();
    
            scanf(" %d", &m);
            while (m--) {
                ans.clear();
                scanf(" %s", s);
                int l = decode(s);
                ac.find(ss, l);
    
                sort(ans.begin(), ans.end());
                int cnt = unique(ans.begin(), ans.end()) - ans.begin();
                printf("%d
    ", cnt);
            }
    
            puts("");
        }
    
        return 0;
    }
    


  • 相关阅读:
    ArrayList 和 Vector 的区别
    Redis在springboot中使用,读取字符串
    初始化Mysql
    Redis 安装
    React-脚手架
    React virtual DOM explained in simple English/简单语言解释React的虚拟DOM
    数据结构
    书单(18-19)
    算法复杂度
    otrs离线部署
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3246914.html
Copyright © 2011-2022 走看看