迷之好奇 SDUTOJ 3039

迷之好奇

Time Limit: 2000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

FF得到了一个有n个数字的集合。不要问我为什么,有钱,任性。

FF很好奇的想知道,对于数字x,集合中有多少个数字可以在x前面添加任意数字得到。

如,x = 123,则在x前面添加数字可以得到4123,5123等。

输入

  多组输入。

对于每组数据

首先输入n(1<= n <= 100000)

接下来n行。每行一个数字y(1 <= y <= 100000)代表集合中的元素。

接下来一行输入m(1 <= m <= 100000),代表有m次询问。

接下来的m行。

每行一个正整数x(1 <= x <= 100000)

输出

  对于每组数据,输出一个数字代表答案。

示例输入

3
12345
66666
12356
3
45
12345
356

示例输出

1
0
1

裸的字典树
    其具体实现:在没有输入任何字符串之前,进行init()即初始化,并且保存返回的结点,便于以后进行建树与查找,在最开始部分init()返回的值相当与根节点,
以此根进行其他节点的拓展。
    根据init()返回的节点为基准进行建树,枚举每个数字或字母,看是否值为-1,若是则在刚开始根节点基础上进行拓展,所得的值付给当前值为-1的节点,并且标记
值要自加,之后再把当期init()返回的值付给k,类似的进行 查找只不过将返回查找结果。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int next[30],bj;
}q[9000000];
char s[64];
int top;
int init()
{
    memset(q[top].next,-1,sizeof(q[top].next));
    q[top].bj=0;
    return top++;
}
void bu(int k,char *s)
{
    int i,j,l;
    l=strlen(s);
    for(i=l-1;i>=0;i--)
    {
        j=s[i]-'0';
        if(q[k].next[j]==-1)
        {
            q[k].next[j]=init();
        }
        q[k].bj++;
        k=q[k].next[j];
    }
}
int  fi(int k,char *s)
{
    int i,j,l;
    l=strlen(s);
    for(i=l-1;i>=0;i--)
    {
        j=s[i]-'0';
        if(q[k].next[j]==-1)
        {
            return 0;
        }
        k=q[k].next[j];
    }
    return q[k].bj;
}
int main()
{
    int n,m,i,j,k;
    ios::sync_with_stdio(false);
    while(cin>>n&&n)
    {
        top=0;
        int root=init();
        while(n--)
        {
            cin>>s;
            bu(root,s);
        }
        cin>>m;
        while(m--)
        {
            cin>>s;
            int p=fi(root,s);
            printf("%d\n",p);
        }
    }
    return 0;
}


你可能感兴趣的:(trie)