SDUT3039迷之好奇

Problem Description

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

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

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

Input

 多组输入。

对于每组数据

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

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

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

接下来的m行。

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

Output

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

Sample Input

3
12345
66666
12356
3
45
12345
356

Sample Output

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

根据字符串反向建树

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int data;
    int next[30];
} q[1000010];
char s[64];
int top;
int Init()
{
    memset(q[top].next, -1, sizeof(q[top].next));
    q[top].data = 0;
    return top++;
}
void Insert(int k, char *s)
{
    int i, j, len;
    len = strlen(s);
    for(i = len-1; i >= 0; i--)
    {
        j = s[i] - '0';
        if(q[k].next[j] == -1)
            q[k].next[j] = Init();
        q[k].data++;
        k = q[k].next[j];
    }
}
int Search(int k, char *s)
{
    int i, j, len;
    len = strlen(s);
    for(i = len-1; i >= 0; i--)
    {
        j = s[i] - '0';
        if(q[k].next[j] == -1)
            return 0;
        k = q[k].next[j];
    }
    return q[k].data;
}
int main()
{
    int n, m;
    while(cin>>n)
    {
        top = 0;
        int root = Init();
        while(n--)
        {
            cin>>s;
            Insert(root, s);
        }
        cin>>m;
        while(m--)
        {
            cin>>s;
            int p = Search(root, s);
            cout<<p<<endl;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/zhj9579/article/details/81667104