zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    gdb调试工具
    一步步理解Linux之中断和异常
    英语感受 5月份英语思维
    2013年6月4日星期二
    2013年5月29日星期三
    2013年6月3日星期一
    第22周六晚上
    2013年5月26日星期日
    2013年5月28日20:16:21
    2013年6月2日星期日
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7372215.html
Copyright © 2011-2022 走看看