zoukankan      html  css  js  c++  java
  • BZOJ1212: [HNOI2004]L语言

    【传送门:BZOJ1212


    简要题意:

      给出n个单词,m个母串,输出每个母串最多能用单词覆盖的最长前缀长度(单词与单词之间不可重叠)


    题解:

      一开始想着用AC自动机,结果发现fail指针一点用也没有

      就直接建字典树,v[i]表示母串1到i能够被单词覆盖,true表示能覆盖,一开始v[0]=true,然后对于一个母串,从头到尾扫一遍,假设当前扫到i点并且i点能够被单词覆盖,则将i+1到len在字典树中跑,加入能跑到一个单词的结尾,v[k]=true(k表示这个单词的结尾位于母串的位置)

      最后从len往前枚举,找到第一个v为true时,输出当前位置即可

      数据竟然有重复的单词出现,害WA了一次


    参考代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    struct trie
    {
        int s,c[27],fail,d;
        trie()
        {
            s=fail=d=0;
            memset(c,-1,sizeof(c));
        }
    }t[210];int cnt;
    char a[210],st[1100000];
    int v[1100000];
    void bt()
    {
        int x=0,len=strlen(a+1);
        for(int i=1;i<=len;i++)
        {
            int y=a[i]-'a'+1;
            if(t[x].c[y]==-1) t[x].c[y]=++cnt;
            x=t[x].c[y];
        }
        t[x].s++;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",a+1);
            bt();
        }
        memset(v,0,sizeof(v));
        for(int i=1;i<=m;i++)
        {
            scanf("%s",st+1);
            int len=strlen(st+1);
            int x=0,ans=0;
            v[0]=i;
            while(x<=len)
            {
                while(v[x]!=i)
                {
                    x++;
                    if(x==len+1) break;
                }
                int j=0;
                for(int k=x+1;k<=len;k++)
                {
                    int y=st[k]-'a'+1;
                    if(t[j].c[y]==-1) break;
                    else
                    {
                        j=t[j].c[y];
                        if(t[j].s>0) v[k]=i;
                    }
                }
                x++;
            }
            for(int j=len;j>=1;j--) if(v[j]==i){ans=j;break;}
            printf("%d
    ",ans);
        }
        return 0;
    }

     

  • 相关阅读:
    155. 最小栈
    160. 相交链表
    PAT 1057 Stack
    PAT 1026 Table Tennis
    PAT 1017 Queueing at Bank
    PAT 1014 Waiting in Line
    PAT 1029 Median
    PAT 1016 Phone Bills
    PAT 1010 Radix
    PAT 1122 Hamiltonian Cycle
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8385636.html
Copyright © 2011-2022 走看看