• [HNOI2004]L语言


    题目:BZOJ1212、洛谷P2292。

    题目大意:给你n个单词和m篇文章,如果一篇文章的前k个字符能分成若干个单词,那么就认为这k个字符能被理解,求每篇文章最多能被理解几个字符。

    解题思路:由于单词长度最大为10,我们建一棵Trie,用c[i]表示前i个字符能否被理解,枚举i,然后从i往后扩展即可。有点类似dp的思想,具体见代码注释。

    找了半天的错发现c数组没清空也是没谁了╮(╯▽╰)╭

    C++ Code:

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,m,ans;
    char s[1000005];
    bool c[1000005];//c[i]表示文章0~i能否被理解
    struct trie{
        bool exist;
        trie* nxt[26];
        trie():exist(false){
            for(int i=0;i<26;++i)nxt[i]=NULL;
        }
    }*d;
    int main(){
        d=new trie;
        scanf("%d%d",&n,&m);
        while(n--){//构造字典树
            scanf("%s",s);
            trie* p=d;
            for(int i=0;s[i];++i){
                int v=s[i]-'a';
                if(p->nxt[v]==NULL)p->nxt[v]=new trie;
                p=p->nxt[v];
            }
            p->exist=true;
        }
        while(m--){//枚举单词开始的节点
            scanf("%s",s);
            ans=0;
            memset(c,0,sizeof(c)); 
            for(int i=0;s[i];++i)
            if(i==0||c[i-1]){//当i为0或前面的文章能被理解时才能继续
                trie* p=d;
                for(int l=1;l<=10;++l){//枚举单词长度
                    if(!s[i+l-1])break;//超过s直接跳出
                    p=p->nxt[s[i+l-1]-'a'];
                    if(p==NULL)break;//不存在这个前缀时直接退出
                    if(p->exist){//成功理解
                        c[i+l-1]=true;
                        if(ans<i+l)ans=i+l;
                    }
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    1082 射击比赛 (20 分)
    1091 N-自守数 (15 分)
    1064 朋友数 (20 分)
    1031 查验身份证 (15 分)
    1028 人口普查 (20 分)
    1059 C语言竞赛 (20 分)
    1083 是否存在相等的差 (20 分)
    1077 互评成绩计算 (20 分)
    792. 高精度减法
    791. 高精度加法
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7372215.html
Copyright © 2020-2023  润新知