boj1302

来源:互联网 发布:office for mac怎么样 编辑:程序博客网 时间:2024/06/01 11:22

Hard problemSubmit: 739   Accepted:199Time Limit: 4000MS  Memory Limit: 200000K

Description
小明在读小学的时候实在是很贪玩,常常旷课跑出去玩,最后终于被老师给逮着了。老师可不会那么轻易地放过他,他得想个法子改改小明这坏习惯。刚好,老师知道小明的数学不好,然后想给他提高提高,怎么办呢?那就数数吧,老师也是个懂点电脑的人,他为了折腾小明,他随机生成了一个大串,然后叫小明去统计里边一些子串出现的次数,但是他怕小明眼花,所以字串的长度都不会超过8,但是取而代之的是会有大量的子串,当然子串可以有部分重叠。但是小明也不是一个笨小孩,他知道这些事情要他自己干的话也就十来二十年吧,不算太多,那也不少,所以他想请求在座的计算机大牛们帮帮他吧。
给一个由小写字母组成的字符串S 长度1<=L<=2^14 再给Q<200000次查询,每次查询都是一个字符串s长度1<=l<=8,要求找出给出的字符串s在S中出现的次数。


Input
多组数据测试
输入由3部分组成:
第一行为字符串S(字符串均由小写字母组成)
第二行为查询次数Q,
接下来为Q 行每行一个字符串.


Output
对应于每个查询的字符串输出此字符串在原字符串S中出现的次数.


Sample Input

ababababab
3
ab
aba
bab
accsafdac
1
ac


Sample Output

Case 1:
5
4
4
Case 2:
2


Source
dreamzk

 

 

来源:http://acm.scs.bupt.cn/onlinejudge/showproblem.php?problem_id=1302

 

 

trie树, 可以以查询串建树,以模式串进行查询,或者以模式串的所有长度小于8的字串建树, 每次查询。

第二种方法的代码:

struct Node
{
        int cnt;
        Node* next[26];
};

void init(Node* trie)
{
     trie->cnt=0;
     for(int i=0; i<26; i++)
     trie->next[i]=NULL;
}
void insert(Node* root, char* str, int len)
{
     Node* p = root;
     int cur;
     for(int i=0; i<len; i++, p=p->next[cur])
     {
             cur = str[i]-'a';
             if(p->next[cur]==NULL)
             {
               p->next[cur]=new Node;
               init(p->next[cur]);
             }
     }
     p->cnt++;
}
int getCnt(Node* root, char* str)
{
    int len = strlen(str);
    Node* p = root;
    int cur;
     for(int i=0; i<len; i++)
     {
             cur = str[i]-'a';
             if(p->next[cur]==NULL)
             return 0;
             p=p->next[cur];
     }
     return p->cnt;
}
void free(Node* root)
{
     if(root==NULL)
     return;
     for(int i=0; i<26; i++)
     free(root->next[i]);
     delete root;
}
char str[(1<<14)+5];
char q[10];
int main()
{
    Node *root;
    int t=0;
    while(scanf("%s", str)!=EOF)
    {
         int n;
         root = new Node;
         init(root);
         int len = strlen(str);
         for(int i=1; i<9; i++)
         {
           for(int j=0; j<len-i+1; j++)
             insert(root, str+j, i);
         }
         scanf("%d", &n);
         printf("Case %d:/n", ++t);
         while(n--)
         {
                   scanf("%s", q);
                   printf("%d/n", getCnt(root, q));
         }
         free(root);       
    }
    return 0;
}

原创粉丝点击