zoukankan      html  css  js  c++  java
  • [JSOI2012]玄武密码 题解(AC自动机)

    显然是AC自动机对吧

    插入单词之后把文章在自动机上跑一遍,到达过的节点打上花火标记

    之后检查一下每个单词有几个标记即可

    可以把题目中的4个字母映射成abcd方便遍历

    一定要记得把文章也映射啊!

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=1e7+5;
    char word[100005][105],s[N];
    int n,m;
    char mapping(char ch)
    {
        switch(ch)
        {
            case 'E':return 'a';break;
            case 'S':return 'b';break;
            case 'W':return 'c';break;
            case 'N':return 'd';break;
        }
    }
    struct AC_auto
    {
        struct node
        {
            node *son[7],*fail,*fa;
            int size;
            bool v;
            node()
            {
                memset(this,0,sizeof(node));
            }
        };
        node *root;
        void ini()
        {
            root=new node;
        }
        void ins(char *str)
        {
            int l=strlen(str+1);
            node *now=root;
            for(int i=1;i<=l;i++)
            {
                if(!now->son[str[i]-'a'])
                    now->son[str[i]-'a']=new node();
                now=now->son[str[i]-'a'];
            }
            now->size++;
        }
        void build()
        {
            queue<node*> q;
            for(int i=0;i<4;i++)
            {
                if(root->son[i])
                {
                    q.push(root->son[i]);
                    root->son[i]->fail=root;
                }
                else root->son[i]=root;
            }
            while(!q.empty())
            {
                node *x=q.front();
                q.pop();
                for(int i=0;i<4;i++)
                {
                    if(x->son[i])
                    {
                        x->son[i]->fail=x->fail->son[i];
                        q.push(x->son[i]);
                    }
                    else x->son[i]=x->fail->son[i];
                }
                
            }
        }
        void query(char *str)
        {
            node *now=root;
            int l=strlen(str+1),i=1;
            while(i<=l)
            {
                now=now->son[str[i]-'a'];
                if(!now)return ;
                for(node *j=now;j!=root&&j->size!=-1;j=j->fail)
                    j->size=-1;
                i++;
            }
        }
        int ans(char *str)
        {
            node *now=root;
            int l=strlen(str+1),i;
            for(i=1;i<=l;i++)
            {
                if(now->son[str[i]-'a']->size>=0)break;
                now=now->son[str[i]-'a'];
            }
            return i-1;
        }
    }ac;
    int main()
    {
        scanf("%d%d%s",&n,&m,s+1);
        for(int i=1;i<=n;i++)s[i]=mapping(s[i]);//Don't forget it!
        ac.ini();
        for(int i=1;i<=m;i++)
        {
            scanf("%s",word[i]+1);
            int l=strlen(word[i]+1);
            for(int j=1;j<=l;j++)word[i][j]=mapping(word[i][j]);
            ac.ins(word[i]);
        }
        ac.build();
        ac.query(s);
        for(int i=1;i<=m;i++)printf("%d
    ",ac.ans(word[i]));
        return 0;
    }
  • 相关阅读:
    设计模式
    mysql引擎与物理文件
    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'socialCode' in 'class java.lang.String'
    bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException
    jedis异常Broken pipe (Write failed)
    java第三方工具包
    mysql安装(centos7)
    sftp安装(linux)
    Snmp oid对应信息
    RAID
  • 原文地址:https://www.cnblogs.com/Rorschach-XR/p/11021952.html
Copyright © 2011-2022 走看看