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;

}

  

 

你可能感兴趣的:(String)