zoukankan      html  css  js  c++  java
  • hdu 3695 DFA

    这题还是比较裸的,可是花了好长时间,一直TLE,最后加上一个优化,当一个字符放到DFA上跑不动的时候,后面相同的字符就直接PASS,终于过了,泪流满面啊……

    /*
    * hdu3695/win.cpp
    * Created on: 2011-9-21
    * Author : ben
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;

    const int MAX_PATTERN_NUM = 260;
    const int MAX_PATTERN_LEN = 1100;
    const int MAXQ = 500000;
    const int MAXK = 26; //字符集的大小
    const char BASE = 'A';

    typedef struct TrieNode {
    TrieNode* fail;
    TrieNode* next[MAXK];
    bool isaend; //该节点是否为某模式串的终结点
    int index; //以该节点为终结点的模式串编号
    } TrieNode;
    TrieNode *myqueue[MAXQ], *root, CTree[MAXQ];

    int N, nCount;
    bool infected[MAX_PATTERN_NUM];

    inline TrieNode * NewTrieNode() {
    CTree[nCount].index = -1;
    return &CTree[nCount++];
    }

    void TrieInsert(char *s, int index) {
    int i = 0;
    TrieNode *ptr = root;
    while (s[i]) {
    int idx = s[i] - BASE;
    if (!ptr->next[idx]) {
    ptr->next[idx] = NewTrieNode();
    }
    ptr = ptr->next[idx];
    i++;
    }
    ptr->isaend = true;
    ptr->index = index;
    }

    void Init() {
    int i;
    char s[MAX_PATTERN_LEN];
    root = NewTrieNode();
    for (i = 0; i < N; i++) {
    scanf("%s", s);
    getchar();
    TrieInsert(s, i);
    reverse(s, s + strlen(s));
    TrieInsert(s, i);
    }
    }

    void Build_DFA() {
    int rear = 1, front = 0, i;
    myqueue[0] = root;
    root->fail = NULL;
    while (rear != front) {
    TrieNode *cur = myqueue[front++];
    for (i = 0; i < MAXK; i++) {
    if (!cur->next[i]) {
    continue;
    }
    if (cur == root) {
    cur->next[i]->fail = root;
    } else {
    TrieNode *ptr = cur->fail;
    while (ptr) {
    if (ptr->next[i]) {
    cur->next[i]->fail = ptr->next[i];
    if (ptr->next[i]->isaend) {
    cur->next[i]->isaend = true;
    }
    break;
    }
    ptr = ptr->fail;
    }
    if (!ptr) {
    cur->next[i]->fail = root;
    }
    }
    myqueue[rear++] = cur->next[i];
    }
    }
    }

    void Run_DFA() {
    int temp;
    char c = getchar();
    TrieNode *ptr = root;
    TrieNode *last = NULL;
    ptr = root;
    while (c > ' ') {
    temp = 1;
    if (c == '[') {
    scanf("%d%c]", &temp, &c);
    }
    while (temp--) {
    last = ptr;
    int idx = c - BASE;
    while (!ptr->next[idx] && ptr != root) {
    ptr = ptr->fail;
    }
    ptr = ptr->next[idx];
    if (!ptr) {
    ptr = root;
    }
    TrieNode *tmp = ptr;
    while (tmp && tmp->isaend) {
    infected[tmp->index] = true;
    tmp = tmp->fail;
    }
    if (ptr == last) {
    break;
    }
    }
    c = getchar();
    }
    }

    int main() {
    #ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
    #endif
    int T;
    scanf("%d", &T);
    while (T--) {
    scanf("%d", &N);
    nCount = 0;
    memset(CTree, 0, sizeof(CTree));
    Init();
    Build_DFA();
    memset(infected, false, sizeof(infected));
    Run_DFA();
    int ans = 0;
    for (int i = 0; i < N; i++) {
    ans += infected[i];
    }
    printf("%d\n", ans);
    }
    return 0;
    }

  • 相关阅读:
    邓亚萍:我是如何学英语的(一种学习方法)
    qemu-nbd方式挂载qcow2镜像
    jquery 手机触摸事件
    用纯CSS创建一个三角形
    什么是闭包(closure),为什么要用它?
    javascript创建对象的几种方式
    如何垂直居中div?面试经常问到
    网页布局——左侧固定,右侧自适应
    python性能:不要使用 key in list 判断key是否在list里
    python实现的跳点寻路算法(JPS)
  • 原文地址:https://www.cnblogs.com/moonbay/p/2184204.html
Copyright © 2011-2022 走看看