zoukankan      html  css  js  c++  java
  • POJ 2896 AC自动机 or 暴力

    DESCRIPTION :大意是说。给你n个代表病毒的字符串。m个表示网站的字符串。让你计算有多少个网站被病毒感染了。被那些病毒感染了。

    刚开始就想暴力。然而,忽略了条件:每个网站最多有三个病毒。于是。TLE了。于是换AC 自动机。于是MLE了。于是把最大的结构体指针数组换成队列。用时间来换空间。23333

    应该注意结构体的初始化是必须的。

    附代码:
    AC 自动机:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    #include<map>
    using namespace std;
    #define T_SIZE 10000
    
    struct trie{
        trie* nexts[128];
        trie* fail;
        int num1, num2;
        int mem;
        trie(){
            for(int i=0;i<128;i++){
                nexts[i]=NULL;
            }
            fail=NULL;
            num1= num2 = 0;
        }
    };
    
    char T[T_SIZE+2];
    queue<struct trie*>que;
    int ans[50];
    map<int, int>mm;
    
    void insert(trie* root,char* s, int m){
        trie* p=root;
        for(int i=0;s[i]!='';i++){
            if(p->nexts[s[i]-0]==NULL)
                p->nexts[s[i]-0]=new trie;
            p=p->nexts[s[i]-0];
        }
        p->num1++;
        p->mem = m;
    }
    
    void build_ac_automation(trie* root){
        que.push(root);
        while(!que.empty()){
            trie* fronts=que.front();
            que.pop();
            for(int i=0;i<128;i++){
                if(fronts->nexts[i]!=NULL){
                    trie* p=fronts->fail;
                    while(p!=NULL){
                        if(p->nexts[i]!=NULL){
                            fronts->nexts[i]->fail=p->nexts[i];
                            break;
                        }
                        p=p->fail;
                    }
                    if(p==NULL){
                        fronts->nexts[i]->fail=root;
                    }
                    que.push(fronts->nexts[i]);
                }
            }
        }
    }
    
    int ac_find(trie* root,char* T){
        trie* p=root;
        int sum=0;
        memset(ans,0,sizeof(ans));
        for(int i=0,len=strlen(T);i<len;i++){
            while(p->nexts[T[i]-0]==NULL && p!=root)
                p=p->fail;
            if(p->nexts[T[i]-0]!=NULL){
                p=p->nexts[T[i]-0];
            }
            trie* temp=p;
            temp->num2 = temp->num1;
            while(temp!=root && temp->num2!=-1){
                temp->num2 = temp->num1;
                if (!mm[temp->mem])
                {ans[sum]=temp->mem+1;
                sum+=temp->num2;}
                temp->num2=-1;
                temp=temp->fail;
            }
        }
        return sum;
    }
    
    int main(){
        int n;
        while(scanf("%d",&n)!= EOF){
                mm.clear();
                int summ=0;
            trie* root=new trie;
            getchar();
            for(int i=0;i<n;i++){
                memset(T,0,sizeof(T));
                gets(T);
                insert(root,T, i);
            }
            build_ac_automation(root);
    
            int t;
            scanf("%d",&t);
            getchar();
            for(int i=0;i<t;i++){
                memset(T,0,sizeof(T));
                gets(T);
                int num=ac_find(root,T);
                if(num!=0){
                    summ++;
                    printf("web %d:",i+1);
                    sort(ans, ans+num);
                    printf(" %d", ans[0]);
                    for(int j=1;j<num;j++){
                        if (ans[j] == ans[j-1])
                            continue;
                        printf(" %d",ans[j]);
                    }
                    printf("
    ");
                }
            }
            printf("total: %d
    ",summ);
        }
        return 0;
    }

  • 相关阅读:
    CSS margin重叠 & CSS BFC(Block Formatting Context)
    require.js
    bind()函数的作用
    JavaScript DOM 总结
    插入排序-直接插入排序、希尔排序
    交换排序-起泡排序、快速排序算法
    JavaScript全局函数
    JavaScript命名空间的理解与实现
    document.documentElement.clientWidth
    Python-删除多级目录
  • 原文地址:https://www.cnblogs.com/icode-girl/p/4671569.html
Copyright © 2011-2022 走看看