hdu 2222 DFA 模板题

来源:互联网 发布:投资域名 后悔死了 编辑:程序博客网 时间:2024/06/11 00:31
真心对此题无奈了。。。。配得上2222这个称号了
题目要求我们算出一个字符串中包含着多少个他给出的单词。
坑爹的是这单词居然有一样的。。。。
如果一样的两个单词被给出,那么答案就应该是2,而不是1
样例如下:
Sample Input:
1
5
ab
ab
ab
ab
ab
ab

Sample Output:
5

有种被骗的赶脚~

#include#include#include#includeusing namespace std;#define Maxn 6010000struct nodes {    nodes * next[26], *fail; //fail 指针指向该节点的最长后缀    int no, inde;} D[Maxn], *Q[Maxn];int tot;nodes *newnodes() {    memset(D[tot].next, 0, sizeof (int) *26);    D[tot].no = 0;    D[tot].inde = tot;    return &D[tot++];}int code(char c) {    return c - 'a';}void insert(char s[], nodes *p, int inp) {    for (int i = 0; s[i]; i++) {        int tmp = code(s[i]);        if (p->next[tmp]) {            p = p->next[tmp];        } else {            p->next[tmp] = newnodes();            p = p->next[tmp];        }    }    p->no += inp;}void buildAC(nodes *p) {    int L = 0, R = 0, i;    for (i = 0; i < 26; i++) {        if (p->next[i]) {            Q[R++] = p->next[i];            p->next[i]->fail = p;        } else {            p->next[i] = p;        }    }    while (L < R) {        p = Q[L++];        for (i = 0; i < 26; i++) {            if (p->next[i]) {                p->next[i]->fail = p->fail->next[i]; //p->next[i]的fail是p的fail的next[i];                Q[R++] = p->next[i];            } else p->next[i] = p->fail->next[i]; //p->next[i]一定不为空.        }    }}char st[1000500];bool mark[10505];int main() {    int N, i, cas;    scanf("%d", &cas);    while (cas--) {        memset(mark, false, sizeof (mark));        char str[90];        scanf("%d", &N);        tot = 0;        nodes *root = newnodes();        for (i = 0; i < N; i++) {            scanf("%s", str);            insert(str, root, 1);            mark[i] = false;        }        buildAC(root);        scanf("%s", st);        nodes *p = root;        nodes *g;        int ans = 0;        for (i = 0; st[i]; i++) {            int tmp = code(st[i]);            p = p->next[tmp];            if (p->no != 0)                ans += p->no;            p->no = 0;            g = p;            while (g->inde != 0) {                g = g->fail;                if (g->no != 0)                    ans += g->no;                g->no = 0;            }        }        printf("%d\n", ans);    }    return 0;}




原创粉丝点击