• zoj 3228 Searching the String 夜


    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3441

    trie       这是一个自动机的题 不过trie就可以解决

    先对长串进行处理 由于后面出现的字符串最长为6 所以以长串每个位置的字符为起点用长度1-6的子串进行建树

    建树时 对树里面的节点要维护 到此节点位置的字符串在原串中出现的位置(多个) 并更新出现的个数和不允许重叠的个数

    然后输入短串时就好处理了

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    const int N=1005;
    const int M=100010;
    const int K=26;
    int I;
    struct node
    {
        int v,next;
    }edge[M*6];
    struct nodeTrie
    {
        int next[K];
        int head;
        int len;
        void initialize()
        {
            head=-1;
            len=0;
            memset(next,-1,sizeof(next));
        }
    }trie[M*6];
    int cnt,root;
    char s[10];
    char ls[M];
    int num[M*6];
    int getNewNode()
    {
        ++cnt;
        trie[cnt].initialize();
        return cnt;
    }
    void addWord(int p,int l,int r)
    {
        for(int i=l;i<r;++i)
        {
            if(trie[p].next[ls[i]-'a']==-1)
            trie[p].next[ls[i]-'a']=getNewNode();
            p=trie[p].next[ls[i]-'a'];
            num[I]=1;
            ++trie[p].len;
            edge[I].v=l;
            edge[I].next=trie[p].head;
            trie[p].head=I;
            for(int t=trie[p].head;t!=-1;t=edge[t].next)
            if(edge[t].v+(i-l+1)<=l)
            {num[I]=num[t]+1;break;}
            ++I;
        }
    }
    void init(int n)
    {
        cnt=-1;I=0;
        root=getNewNode();
        for(int i=0;i<n;++i)
        addWord(root,i,min(i+6,n));
    }
    int searchWord(int p,char *s)
    {
        for(int i=0;s[i]!='\0';++i)
        {
            if(trie[p].next[s[i]-'a']==-1)
            return 0;
            p=trie[p].next[s[i]-'a'];
        }
        return p;
    }
    int findNum(char *s,int flag)
    {
        int p=searchWord(root,s);
        if(p==0) return 0;
        if(flag==0)
        return trie[p].len;
        if(trie[p].len<=1)
        return trie[p].len;
        return num[trie[p].head];
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int ca=0;
        while(gets(ls))
        {
            ++ca;
            init(strlen(ls));
            int n;
            scanf("%d",&n);
            printf("Case %d\n",ca);
            while(n--)
            {
                int flag;
                scanf("%d ",&flag);
                gets(s);
                printf("%d\n",findNum(s,flag));
            }
            printf("\n");
            scanf(" ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    [20220314联考] 旅行
    [ZJOI2015] 地震后的幻想乡
    [20220315联考] 等你哈苏德
    [20220318联考] 无向图
    java线程池ThreadPoolTaskExecutor执行顺序
    数据结构单向链表的实现(内含c代码,已调试,可用)
    数据结构双向链表的实现(内含c代码,已调试,可用)
    Python回顾
    220221220223
    言论1
  • 原文地址:https://www.cnblogs.com/liulangye/p/2989203.html
Copyright © 2020-2023  润新知