1. 程式人生 > >SDUTOJ3039迷之好奇(字典樹)

SDUTOJ3039迷之好奇(字典樹)

迷之好奇

Time Limit: 2000 ms Memory Limit: 65536 KiB

Submit Statistic

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

Hint

 

Source

zmx

裸字典樹(倒著建立樹)

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int cnt;       //出現該數字的次數
    int nextt[11]; // 存下一層的代號 就是那個top的值
};
node tree[1000000];
int top;
int creat()
{
    memset(tree[top].nextt, -1, sizeof(tree[top].nextt));
    tree[top].cnt = 0;
    return top++; // 返回代號
}
void insert(int k, char *str)
{
    int len = strlen(str);
    for (int i = len - 1; i >= 0; i--)
    {
        int index = str[i] - '0';
        if (tree[k].nextt[index] == -1)
            tree[k].nextt[index] = creat();
        tree[k].cnt++;            //出現該數字的次數
        k = tree[k].nextt[index]; // 將下一層的對應的代數(top)賦給k
    }
}
int search(int k, char *str)
{
    int len = strlen(str);
    for (int i = len - 1; i >= 0; i--)
    {
        int index = str[i] - '0';
        if (tree[k].nextt[index] == -1)
            return 0; // 只要一個找不到就返回 0

        k = tree[k].nextt[index]; // 找到 將該數的下一層的代數傳給K
    }
    return tree[k].cnt; // 數字出現次數
}
int main()
{
    int m, n;
    char s[19];
    while (cin >> n)
    {
        top = 0;
        int root = creat();
        for (int i = 0; i < n; i++)
        {
            cin >> s;
            insert(root, s);
        }
        cin >> m;
        for (int i = 0; i < m; i++)
        {
            cin >> s;
            int ans = search(root, s);
            cout << ans << endl;
        }
        // cout<<endl;
    }
    return 0;
}