hdu 2846 Repository

来源:互联网 发布:淘宝培训kehuda 编辑:程序博客网 时间:2024/05/18 01:58

很神奇的一道题!!用g++提交死活不给过,一直说超内存,后来改c++就过了。

题意:是给出一些模式串,再给出几个询问,询问给出的字符串在多少个在模式串中出现

解法:字典树解决,字典树能很好的处理前缀出现的次数,将模式串分解,依次插入字典树中。

需要注意的是对于同一个模式串的不同子串可能有相同的前缀,为了避免多次计算,可以添加字典树节点的信息,添加num记录插入的字符串是第num个模式串的子串。

#include<stdio.h>#include<string.h>#include<malloc.h>struct node{    int cnt,num;    node *next[26];    node()    {        cnt=0;        num=0;        for(int i=0;i<26;i++)            next[i]=NULL;    }}*p,*tmp;node *root=new node;void mt(char *st,int k){    p=root;    int len=strlen(st),j;    for(int i=0;i<len;i++)    {        j=st[i]-'a';        if(p->next[j]==NULL)        {            p->next[j]=new node;            p=p->next[j];            p->cnt++;            p->num=k;        }        else        {            p=p->next[j];            if(p->num!=k)            {                p->cnt++;                p->num=k;            }        }    }}int sm(char *ss){    int len=strlen(ss),j;    tmp=root;    for(int i=0;i<len;i++)    {        j=ss[i]-'a';        if(tmp->next[j]==NULL)            return 0;        tmp=tmp->next[j];    }    return tmp->cnt;}void dt(node *T){    if(T==NULL)        return;    for(int i=0;i<26;i++)        if(T->next[i])            dt(T->next[i]);    free(T);    return;}int main(){    int n;    char str[25],s[25];    scanf("%d",&n);    root=new node;    for(int i=1;i<=n;i++)    {        scanf("%s",str);        int len=strlen(str);        for(int j=0;j<len;j++)        {            strncpy(s,str+j,len-j);            s[len-j]='\0';            mt(s,i);        }    }    int Q;    scanf("%d",&Q);    for(int i=0;i<Q;i++)    {        scanf("%s",str);        printf("%d\n",sm(str));    }    dt(root);    return 0;}



 


0 0
原创粉丝点击