QDU65 again and again(字典序暴力or字典树)

xx学习了Trie树后,向你问了一个问题,给定一个字符串集合S={str1, str2, ,strn}和一个字符串s,在s的后面接尽量少的字符,使其属于集合S。当然如果s本身就属于Ss就是答案。

第一行一个正整数T(T <= 10),表示有T组数据。 每组数据输入格式如下: 第一行为一个正整数N(0<N<20000),表示字符串集合内的字符串数。 接下来N行,每行一个字符串,表示集合中的串。 接下来一行是一个正整数Q(0<Q<200),表示有Q次询问。 接下来Q行,每行一个字符串str。 所有字符串均由小写英文字母组成,且1<=长度<=20。

每组数据输出格式如下: 先输出“Case x:”,x表示是第几组数据,然后输出一个换行。 接下来输出Q行,对于每次询问,如果str能够添加字符使其属于字符串集合,则输出长度最小的(即str添加字符后构成的串),有多个满足条件的话输出字典序最小的。否则输出-1。

复制
3
3
abc
abd
aba
3
ab
ad
abc
2
bcde
bcdef
1
bcd
3
abc
def
hig
1
kkkk
Case 1:
aba
-1
abc
Case 2:
bcde
Case 3:
-1

字典树写法:
#include <bits/stdc++.h>
using namespace std;
int T;
int N;
char s[100];
int dp[500010];
int NN[500010];
int ch[500010];
struct tire
{
    int L,root,End[500010], Next[500010][27];
    int newnode()
    {
        for(int i=0; i<26; i++)
            Next[L][i] = -1;
        End[L++] = 0;
        return L-1;
    }
    void init()
    {
        L = 0;
        root = newnode();
    }
    void insert(char *tmp)
    {
        int len = strlen(tmp);
        int now = root;
        for(int i=0; i<len; i++)
        {
            if(Next[now][s[i]-'a'] == -1)
                Next[now][s[i]-'a'] = newnode();
            now = Next[now][s[i]-'a'];
        }
        End[now] = 1;
    }
    void dfs(int now)
    {
        if(End[now] == 1)
        {
            dp[now] = 0;
        }
        for(int i=0; i<26; i++)
        {
            int nn = Next[now][i];
            if(nn != -1)
            {
                dfs(nn);
                if(dp[now] > dp[nn] + 1)
                {
                    dp[now] = dp[nn] + 1;
                    NN[now] = nn;
                    ch[now] = i;
                }
                else if(dp[now] == dp[nn] + 1 && ch[now] > i)
                {
                    NN[now] = nn;
                    ch[now] = i;
                }
            }
        }
    }
    int query(char *tmp)
    {
        int len = strlen(tmp);
        int now = root;
        for(int i=0; i<len; i++)
        {
            if(Next[now][s[i]-'a'] == -1)
                return -1;
            now = Next[now][s[i]-'a'];
        }
        return now;
    }
} Trie;
int q;
int main()
{
    cin>>T;
    int icase = 0;
    while(T--)
    {
        memset(NN, -1, sizeof(NN));
        memset(ch, -1, sizeof(ch));
        memset(dp, 0x3f3f3f3f, sizeof(dp));
        cin>>N;
        Trie.init();
        for(int i=1; i<=N; i++)
        {
            scanf("%s", s);
            Trie.insert(s);
        }
        Trie.dfs(Trie.root);
        cin>>q;
        printf("Case %d:\n", ++icase);
        while(q--)
        {
            scanf("%s", s);
            int res = Trie.query(s);
            if(res == -1)
            {
                printf("-1\n");
                continue;
            }
            printf("%s", s);
            while(true)
            {
                if(Trie.End[res] == 1) break;
                printf("%c", (char)(ch[res] + 'a'));
                res = NN[res];
            }
            printf("\n");
        }
    }
    return 0;
}

 

暴力写法:

#include <bits/stdc++.h>
using namespace std;

struct Node
{
    char str[25];
    int len;
};

Node node[20010];

bool cmp(Node x, Node y)
{
    return (x.len < y.len || (x.len == y.len && strcmp(x.str, y.str) < 0));
}

int main()
{
    int t, tt = 1;
    scanf("%d", &t);
    while(t--)
    {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%s", node[i].str);
            node[i].len = strlen(node[i].str);
        }
        sort(node + 1, node + 1 + n, cmp);
        int q;
        printf("Case %d:\n", tt++);
        scanf("%d", &q);
        while(q--)
        {
            char str[25];
            scanf("%s", str);
            int i;
            for(i = 1; i <= n; i++)
            {
                if(strstr(node[i].str, str) == node[i].str)
                {
                    printf("%s\n", node[i].str);
                    break;
                }
            }
            if(i == n + 1) printf("-1\n");
        }
    }
    return 0;
}

 

posted on 2016-01-04 10:01  恶devil魔  阅读(188)  评论(0编辑  收藏  举报

导航