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

    还是赤裸裸的DFA,第一次交居然MLE,正苦恼时,看了一眼Discuss,有人说他把数据大小开成80000就过了,我一改,果然过了,汗啊,我之前开的是100000~

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

    const int MAX_PATTERN_NUM = 510;
    const int MAX_PATTERN_LEN = 210;
    const int MAXQ = MAX_PATTERN_NUM * MAX_PATTERN_LEN;
    const int MAX_TEXT_LEN = 10100;
    const int MAXK = 95; //字符集的大小
    const char BASE = '!';

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

    //文本字符串及模式串
    char msg[MAX_TEXT_LEN];
    char pattern[MAX_PATTERN_LEN];
    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;
    root = NewTrieNode();
    for (i = 1; i <= N; i++) {
    scanf("%s", pattern);
    TrieInsert(pattern, i);
    }
    }

    void Build_DFA() {
    int rear = 1, front = 0, i;
    que[0] = root;
    root->fail = NULL;
    while (rear != front) {
    TrieNode *cur = que[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;
    }
    }
    que[rear++] = cur->next[i];
    }
    }
    }

    void Run_DFA() {
    int i = 0;
    TrieNode *ptr = root;
    ptr = root;
    while (msg[i]) {
    int idx = msg[i] - 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;
    }
    i++;
    }
    }

    int main() {
    #ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
    #endif
    int M, total;
    while (scanf("%d", &N) == 1) {
    nCount = 0;
    total = 0;
    memset(CTree, 0, sizeof(CTree));
    Init();
    Build_DFA();
    scanf("%d", &M);
    for (int i = 1; i <= M; i++) {
    memset(infected, false, sizeof(infected));
    scanf("%s", msg);
    Run_DFA();
    int temp = 0;
    for (int j = 1; j <= N; j++) {
    temp += infected[j];
    }
    if (temp > 0) {
    total++;
    printf("web %d:", i);
    for (int j = 1; j <= N; j++) {
    if (infected[j]) {
    printf(" %d", j);
    }
    }
    putchar('\n');
    }
    }
    printf("total: %d\n", total);
    }
    return 0;
    }

  • 相关阅读:
    硬盘任性丢数据,但分布式存储一定可靠吗?
    Service的基本组成
    固定cell.imageView.image的大小
    剪贴板服务
    取得正在运行的Activity
    取得正在运行的服务
    C#.NET学习笔记1---C#.NET简介
    取得手机的网络信息
    四、cocos2dx动画Animation介绍
    C#.NET学习笔记2---C#.第一个C#程序
  • 原文地址:https://www.cnblogs.com/moonbay/p/2184864.html
Copyright © 2011-2022 走看看