zoukankan      html  css  js  c++  java
  • [BZOJ 1212] L语言

    Link:

    BZOJ 1212 传送门

    Solution:

    看到字符串的多模式匹配,正解一般就是Trie树/AC自动机

    此题由于每个模式串长度都很小,于是直接在Trie树上暴力就行了

    先把所有模式串建一颗Trie树,

    用$DP[i]$表示能否匹配到第$i$个字符,如果能,则从第$i+1$位开始继续从根开始匹配,查看能否拓展答案

    上述偏暴力的做法复杂度在$O(4*10^8)$左右,

    好像还有一种用AC自动机+状压DP的做法能降到$O(10^6)$,后面再填吧

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN=1e6+10;
    struct trie
    {
        int ch[30];
        bool flag;
    }tr[300];
    
    int n,m,dp[MAXN],cnt=1;
    char s[MAXN];
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)  //建立Trie树
        {
            scanf("%s",s);
            int cur=1,len=strlen(s);
            for(int j=0;j<len;j++)
            {
                if(!tr[cur].ch[s[j]-'a']) tr[cur].ch[s[j]-'a']=++cnt;
                cur=tr[cur].ch[s[j]-'a'];
            }
            tr[cur].flag=true;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s);memset(dp,0,sizeof(dp));
            int len=strlen(s);dp[0]=1;
            for(int j=0;j<len;j++)
            {
                if(!dp[j]) continue;
                int cur=1,k=j;
                while(tr[cur].ch[s[k]-'a'])
                {
                    cur=tr[cur].ch[s[k++]-'a'];
                    if(tr[cur].flag) dp[k]=1;
                }
            }
            for(int j=len;j>=0;j--)
                if(dp[j]){printf("%d
    ",j);break;} 
        }
        return 0;
    }

    Review:

    看到多模式匹配,往Trie+AC自动机上想就对了

  • 相关阅读:
    python 根据数组生成图片
    c++ 字符串转数字
    python 迷宫问题
    JavaScript 判断是否为空
    JavaScript 字符串转数字(整数,浮点数,进制转换)
    c++ 珊格迷宫问题
    python eval的用法
    python pillow 处理图片
    c 结构体
    python pillow 绘制图片
  • 原文地址:https://www.cnblogs.com/newera/p/9120508.html
Copyright © 2011-2022 走看看