• BZOJ 1212 && Luogu 2292 [HNOI 2004] L语言


    BZOJ题面

    Luogu题面

    刚学 Trie 碰到这题差点懵逼

    表示加了个 DP 我差点就不会了

    主要讲一下 DP 的思路

    F[i] == 1 表示以第 i 个字符(从 0 开始)结尾的字符串能被理解

    同理,F[i] == 0 表示不能理解

    当满足 F[j] == 1 且以 F[j+1] 开头,以 F[i] 结尾的单词在 Trie 内

    把 F[i] 置为 1

    最后只要输出一个最大的 i 使得 F[i] == 1 即可

    蒟蒻专属暴力思路,好想又好写,但奇慢无比,在 Luogu 上第十个点 TLE,幸亏有 O2 这种神奇的东西

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int cnt,f[1050000];
    char a[11],s0[1050000];
    queue<int>q;
    struct tree{  // Trie
        int fail,end,vis[26];
    }ac[220];
    inline void build(char s[]){  // 建 Trie
        int l=strlen(s),now=0;
        for(int i=0;i<l;i++){
            int ch=s[i]-'a';  // 优化:少算 2 次减法
            if(!ac[now].vis[ch]) ac[now].vis[ch]=++cnt;
            now=ac[now].vis[ch];
        }
        ac[now].end=1;  // 标记单词末尾
    }
    inline bool query(int l,int r){  // 查询以 l 和 r 为两端的单词是否在 Trie 内
        int u=0;
        for(int i=l;i<=r;i++){
            int ch=s0[i]-'a';
            if(!ac[u].vis[ch]) return 0;  // 节点不存在则返回 False
            u=ac[u].vis[ch];
        }
        return ac[u].end;
    }
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        while(n--){
            scanf("%s",a);
            build(a);
        }
        while(m--){
            scanf("%s",s0);
            int l=strlen(s0),ans=0;
            for(int i=0;i<l;i++) f[i]=0;
            for(int i=0;i<l;i++){
                for(int j=max(i-10,-1);j<=i;j++)  // 单词长度最大为 10,所以 DP 前 10 个字符
                    if((j==-1||f[j])&&query(j+1,i)){  // 字符串下标从 0 开始,所以把 DP 最小值设为 -1
                        f[i]=1;
                        ans=i+1;  // 下标为 i 的字符是第 i+1 个
                        break;
                    }
                    if(i-9>ans) break;  // 长于单词长度后立即跳出
            }
            printf("%d
    ",ans);
        }
        return 0;
    }

    By The_Seventh

    2017-12-29  08:06:39

  • 相关阅读:
    1001. 害死人不偿命的(3n+1)猜想 (15)
    单链表排序
    简单插入排序
    简单选择排序
    C语言-随机数
    二分查找(折半查找)
    顺序查找-顺序查找-带哨兵查找
    队列-链表实现
    循环队列_数组实现
    队列-顺序存储-简单实现
  • 原文地址:https://www.cnblogs.com/TheSeventh/p/8142635.html
Copyright © 2020-2023  润新知