• ZOJ 3430 Detect the Virus(AC自动机 + 模拟)题解


    题意:问你主串有几种模式串。但是所有串都是加密的,先解码。解码过程为:先把串按照他给的映射表变成6位数二进制数,然后首尾衔接变成二进制长串,再8位8位取变成新的数,不够的补0。因为最多可能到255,所以不能用char存,要用int。

    思路:模拟乱搞一下,加个板子完事。

    代码:

    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 550 * 64 + 10;
    const int M = maxn * 30;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1000000007;
    char s[maxn];
    int bit[maxn * 8], now[maxn * 8];
    map<int, int> change;
    void init(){
        change.clear();
        for(int i = 0; i <= 25; i++)
            change['A' + i] = i;
        for(int i = 26; i <= 51; i++)
            change['a' + i - 26] = i;
        for(int i = 52; i <= 61; i++)
            change['0' + i - 52] = i;
        change['+'] = 62;
        change['/'] = 63;
    }
    int sp(){
        int len = strlen(s);
        int num = 0;
        for(int i = 0; i < len; i++){
            if(s[i] == '='){
                num -= 2;
                continue;
            }
            int k = change[s[i]];
            for(int j = 5; j >= 0; j--){
                bit[num++] = ((k & (1 << j)) == 0? 0 : 1);
            }
        }
        int cnt = 0;
        for(int i = 0; i < num; i += 8){
            now[cnt] = 0;
            for(int j = i; j <= i + 7; j++){
                now[cnt] = now[cnt] * 2 + bit[j];
            }
            cnt++;
        }
        return cnt;
    }
    
    struct Aho{
        struct state{
            int next[260];
            int fail, cnt;
        }node[maxn];
        int size;
        queue<int> q;
    
        void init(){
            size = 0;
            newtrie();
            while(!q.empty()) q.pop();
        }
    
        int newtrie(){
            memset(node[size].next, 0, sizeof(node[size].next));
            node[size].cnt = node[size].fail = 0;
            return size++;
        }
    
        void insert(int s[], int len, int id){
            int now = 0;
            for(int i = 0; i < len; i++){
                int c = s[i];
                if(node[now].next[c] == 0){
                    node[now].next[c] = newtrie();
                }
                now = node[now].next[c];
            }
            node[now].cnt = id;
        }
    
        void build(){
            node[0].fail = -1;
            q.push(0);
    
            while(!q.empty()){
                int u = q.front();
                q.pop();
                for(int i = 0; i < 260; i++){
                    if(node[u].next[i]){
                        if(u == 0) node[node[u].next[i]].fail = 0;
                        else{
                            int v = node[u].fail;
                            while(v != -1){
                                if(node[v].next[i]){
                                    node[node[u].next[i]].fail = node[v].next[i];
                                    break;
                                }
                                v = node[v].fail;
                            }
                            if(v == -1) node[node[u].next[i]].fail = 0;
                        }
                        q.push(node[u].next[i]);
                    }
                }
            }
        }
    
    
        set<int> res;
        void get(int u){ //匹配规则
            while(u){
                if(node[u].cnt) res.insert(node[u].cnt);
                u = node[u].fail;
            }
        }
    
        int match(int s[], int len){
            res.clear();
            int ret = 0, now = 0;
            for(int i = 0; i < len; i++){
                int c = s[i];
                if(node[now].next[c]){
                    now = node[now].next[c];
                }
                else{
                    int p = node[now].fail;
                    while(p != -1 && node[p].next[c] == 0){
                        p = node[p].fail;
                    }
                    if(p == -1) now = 0;
                    else now = node[p].next[c];
                }
                get(now);
            }
            return res.size();
        }
    }ac;
    int main(){
        init();
        int n;
        while(~scanf("%d", &n)){
            ac.init();
            for(int i = 1; i <= n; i++){
                scanf("%s", s);
                int len = sp();
                ac.insert(now, len, i);
            }
            ac.build();
            int m;
            scanf("%d", &m);
            while(m--){
                scanf("%s", s);
                int len = sp();
                printf("%d
    ", ac.match(now, len));
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    美剧基本演绎法福尔莫斯的一句话
    HowToDoInJava 其它教程 1 &#183; 翻译完成
    我们关于版权保护的意见与建议
    HowToDoInJava Spring 教程·翻译完成
    【转】21世纪律师办公自动化的一个调查
    iBooker AI+财务提升星球 2020.4 热门讨论
    布客·ApacheCN 翻译校对活动进度公告 2020.5
    数据可视化的基础知识·翻译完成
    Java 高效编程(Effective Java)中文第三版(补档)
    布客&#183;ApacheCN 编程/大数据/数据科学/人工智能学习资源 2020.4
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11176943.html
Copyright © 2020-2023  润新知