【USACO14FEB】洛谷2237 Auto-complete

78 篇文章 0 订阅
76 篇文章 0 订阅

题目描述

Bessie the cow has a new cell phone and enjoys sending text messages,
although she keeps making spelling errors since she has trouble typing
on such a small screen with her large hooves. Farmer John has agreed
to help her by writing an auto-completion app that takes a partial
word and suggests how to complete it.

The auto-completion app has access to a dictionary of W words, each
consisting of lowercase letters in the range a..z, where the total
number of letters among all words is at most 1,000,000. The app is
given as input a list of N partial words (1 <= N <= 1000), each
containing at most 1000 lowercase letters. Along with each partial
word i, an integer K_i is also provided, such that the app must find
the (K_i)th word in alphabetical order that has partial word i as a
prefix. That is, if one ordered all of the valid completions of the
ith partial word, the app should output the completion that is (K_i)th
in this sequence.

贝西新买了手机,打字不方便,请设计一款应用,帮助她快速发消息。

字典里有W(W<=30000)个小写字母构成的单词,所有单词的字符总数量不超过1,000,000,这些单词是无序的。现在给出N(1 <= N
<=
1000)个询问,每个询问i包含一个的字符串s_i(每个字符串最多包含1000个字符)和一个整数K_i,对于所有以s_i为前缀的单词,其中按字典序排序后的第K_i个单词,求该单词在原字典里的序号。
输入输出格式 输入格式:

Line 1: Two integers: W and N.

Lines 2..W+1: Line i+1: The ith word in the dictionary.
Lines W+2..W+N+1: Line W+i+1: A single integer K_i followed by a partial word.

输出格式:

Lines 1..N: Line i should contain the index within the dictionary

(an integer in the range 1..W) of the (K_i)th completion (in

alphabetical order) of the ith partial word, or -1 if there

are less than K_i completions.

把每个字符串插入trie中,顺便记录下每个结点经过的字符串个数。
对于每个询问在每个节点上按照个数找就可以了,有点类似字典序解码。

#include<cstdio>
#include<cstring>
const int a_s=26;
int trie[1000002][27],num[1000010],tot,size[1000010];
char s[1000010];
int main()
{
    int i,j,k,m,n,p,q,x,y,z,l,u;
    bool flag;
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        l=strlen(s+1);
        p=0;
        for (j=1;j<=l;j++)
        {
            size[p]++;
            x=s[j]-'a'+1;
            if (!trie[p][x]) trie[p][x]=++tot;
            p=trie[p][x];
        }
        size[p]++;
        num[p]=i;
    }
    while (m--)
    {
        scanf("%d%s",&u,s+1);
        l=strlen(s+1);
        p=0;
        flag=1;
        for (i=1;i<=l;i++)
        {
            x=s[i]-'a'+1;
            if (!trie[p][x])
            {
                flag=0;
                break;
            }
            p=trie[p][x];
        }
        if (flag==0||size[p]<u)
        {
            printf("-1\n");
            continue;
        }
        while (1)
        {
            if (num[p]) u--;
            if (!u)
            {
                printf("%d\n",num[p]);
                break;
            }
            for (i=1;i<=a_s;i++)
              if (trie[p][i])
              {
                x=trie[p][i];
                if (size[x]<u) u-=size[x];
                else
                {
                    p=x;
                    break;
                }
              }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值