HDU-3695 Computer Virus on Planet Pandora(ac自动机模板题)

探讨外星AliensonplanetPandora的计算机病毒扫描算法,他们如何从地球学习并应用到自己的程序中,包括病毒模式串匹配及AC自动机实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Aliens on planet Pandora also write computer programs like us. Their programs only consist of capital letters (‘A’ to ‘Z’) which they learned from the Earth. On
planet Pandora, hackers make computer virus, so they also have anti-virus software. Of course they learned virus scanning algorithm from the Earth. Every virus has a pattern string which consists of only capital letters. If a virus’s pattern string is a substring of a program, or the pattern string is a substring of the reverse of that program, they can say the program is infected by that virus. Give you a program and a list of virus pattern strings, please write a program to figure out how many viruses the program is infected by.

多模式串匹配,只不过反着也算。

正着跑一遍倒着跑一遍就好了。

输入比较奇葩,要进行展开,把那个数字看成小于10了一直wa…..

单独给个scanf就ac了。

还有就是重复使用char数组记得最后加‘\0’终止符。

其实这里还是string好用。

记录模板。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1005 * 251;
char pa[5100005];

struct AC_Automaton {
    int next[maxn][26];
    int fail[maxn];
    int end[maxn];
    int sz, root;

    int newNode() {
        for(int i = 0; i < 26; i++) {
            next[sz][i] = -1;
        }
        fail[sz] = -1;
        end[sz] = 0;
        return sz++;
    }

    void init() {
        sz = 0;
        root = newNode();
    }

    void add(char s[]) {
        int p = root, c;
        for(int i = 0, len = strlen(s); i < len; i++) {
            c = s[i] - 'A';
            if(next[p][c] == -1) {
                next[p][c] = newNode();
            }
            p = next[p][c];
        }
        end[p] = 1;
    }


    void getFail() {
        queue<int> q;
        for(int i = 0; i < 26; i++) {
            if(~next[root][i]) {
                fail[next[root][i]] = root;
                q.push(next[root][i]);
            } else {
                next[root][i] = root;
            }
        }
        while(!q.empty()) {
            int p = q.front();
            q.pop();
            for(int i = 0; i < 26; i++) {
                if(~next[p][i]) {
                    fail[next[p][i]] = next[fail[p]][i];
                    q.push(next[p][i]);
                } else {
                    next[p][i] = next[fail[p]][i];
                }
            }
        }
    }

    int solve() {
        int p = root, ans = 0, len = strlen(pa);
        for(int i = 0; i < len; i++) {
            p = next[p][pa[i] - 'A'];
            for(int t = p; t && ~end[t]; t = fail[t]) {
                ans += end[t];
                end[t] = -1;
            }
        }
        p = root;
        for(int i = len - 1; i >= 0; i--) {
            p = next[p][pa[i] - 'A'];
            for(int t = p; t && ~end[t]; t = fail[t]) {
                ans += end[t];
                end[t] = -1;
            }
        }
        return ans;
    }
} ac;


int main() {
    int t, n;
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        ac.init();
        while(n--) {
            scanf("%s", pa);
            ac.add(pa);
        }
        ac.getFail();
        char in = getchar();
        int idx = 0;
        while(in = getchar(), in != '\n') {
            if(in != '[') {
                pa[idx++] = in;
                continue;
            }
            int num;
            scanf("%d", &num);
            in = getchar();
            for(int i = 0; i < num - '0'; i++) {
                pa[idx++] = in;
            }
            getchar();
        }
        pa[idx] = '\0';
        printf("%d\n", ac.solve());
    }
    return 0;
}

吐槽:无论是ac自动机还是后缀自动机,都只有写在结构体里才有感觉自己建了一个“自动机”啊!还有就是写在结构体里就不怕名称跟stl冲突了,找回了写java的感觉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值