zoukankan      html  css  js  c++  java
  • hdu 2896(AC自动机)

    题意:其实我觉得题意是不明确的,而且测试数据很水,各种错误代码也能够AC。

    分析:我认为还有一种理解:就是为连续匹配,模式串中不能出现交叉重复,如:有两种病毒:ab,ba,网站名是:aba答案是web 1: 1 ;total: 1我很纠结!!因为AC代码的答案是:web 1: 1 2;total 1。还有一种理解就是可以交叉重复,我是按照后面这种思路写的代码。

    我发现很多AC代码这组数据是过不了的:

    2
    sher
    he
    2
    she
    sher
    结果应该是
    web 1: 2
    web 2: 1 2
    total: 2

    代码实现:

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<iostream>
    #include<queue>
    using namespace std;

    struct node{
        int next[94];
        int fail;
        int num;
        void init()
        {
            memset(next,0,sizeof(next));
            fail=0;
            num=0;
        }
    }a[100005];
    char keyword[205];
    char S[10005];
    int tot,bianhao,shuliang;

    void chushihua()
    {
        tot=0;
        bianhao=0;
        shuliang=0;
        a[0].init();
    }

    void insert(char *str)
    {
        int index,p;
        p=0;
        for(;*str!='\0';str++)
        {
            index=*str-32;
            if(a[p].next[index]==0)
            {
                a[++tot].init();
                a[p].next[index]=tot;
            }
            p=a[p].next[index];
        }
        a[p].num=++bianhao;
    }

    void build_ac()
    {
        queue<int>Q;
        int i,p,cur,son;
        Q.push(0);
        while(!Q.empty())
        {
            p=Q.front();
            Q.pop();
            for(i=0;i<94;i++)
            {
                if(a[p].next[i]!=0)
                {
                    son=a[p].next[i];
                    cur=a[p].fail;
                    if(p==0)
                        a[son].fail=0;
                    else
                    {
                        while(cur!=0&&a[cur].next[i]==0)
                            cur=a[cur].fail;
                        a[son].fail=a[cur].next[i];
                    }
                    Q.push(son);
                }   
            }
        }
    }

    void solve(int i)
    {
        priority_queue<int,vector<int>,greater<int> >Q;
        int p=0,temp,index,j;
        for(j=0;S[j]!='\0';j++)
        {
            index=S[j]-32;
            while(p!=0&&a[p].next[index]==0)
                p=a[p].fail;
            if(a[p].next[index]!=0)
                p=a[p].next[index];
            temp=p;
            while(temp!=0)
            {
                if(a[temp].num!=0)
                    Q.push(a[temp].num);
                temp=a[temp].fail;
            }
        }
        if(!Q.empty())
        {
            shuliang++;
            printf("web %d:",i);
            while(!Q.empty())
            {
                printf(" %d",Q.top());
                Q.pop();
            }
            printf("\n");
        }
    }


    int main()
    {
        int i,n,m;
        while(scanf("%d",&n)!=EOF)
        {
            chushihua();
            getchar();
            while(n--)
            {
                scanf("%s",keyword);
                insert(keyword);
            }
            build_ac();
        /*    for(i=0;i<=9;i++)
                printf("%d ",a[i].num);
            printf("\n");
            */
            scanf("%d",&m);
            getchar();
            for(i=1;i<=m;i++)
            {
                scanf("%s",S);
                solve(i);
            }
            printf("total: %d\n",shuliang);
        }
        return 0;
    }

  • 相关阅读:
    PB数据窗口分页
    Oracle创建视图权限不足
    PB计算两个日期相差月份(计算工龄)
    oracle笔记之计算年龄、工龄和TRUNC
    oracle随笔之提示“ORA-01002: 提取违反顺序”
    PB笔记之调用数据窗口时的过滤条件添加方式
    Oracle随笔之用拆分后的列数据关联表查询
    四种布局
    Android控件常见属性
    Activity启动活动最佳写法
  • 原文地址:https://www.cnblogs.com/jiangjing/p/3038514.html
Copyright © 2011-2022 走看看