CodeForces - 633C Spy Syndrome 2—好题(hash或字典树)

本文介绍了一个密文破解问题,通过构建逆向字典树并使用哈希算法,成功解析了一种特殊的密文转换规则,即将原文中的大写字母转换为小写并进行单词级别的反转,最终实现了对密文的正确还原。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

After observing the results of Spy Syndrome, Yash realised the errors of his ways. He now believes that a super spy such as Siddhant can't use a cipher as basic and ancient as Caesar cipher. After many weeks of observation of Siddhant’s sentences, Yash determined a new cipher technique.

For a given sentence, the cipher is processed as:

  1. Convert all letters of the sentence to lowercase.
  2. Reverse each of the words of the sentence individually.
  3. Remove all the spaces in the sentence.

For example, when this cipher is applied to the sentence

Kira is childish and he hates losing

the resulting string is

ariksihsidlihcdnaehsetahgnisol

Now Yash is given some ciphered string and a list of words. Help him to find out any original sentence composed using only words from the list. Note, that any of the given words could be used in the sentence multiple times.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 10 000) — the length of the ciphered text. The second line consists of n lowercase English letters — the ciphered text t.

The third line contains a single integer m (1 ≤ m ≤ 100 000) — the number of words which will be considered while deciphering the text. Each of the next m lines contains a non-empty word wi (|wi| ≤ 1 000) consisting of uppercase and lowercase English letters only. It's guaranteed that the total length of all words doesn't exceed 1 000 000.

Output

Print one line — the original sentence. It is guaranteed that at least one solution exists. If there are multiple solutions, you may output any of those.

Examples

Input

30
ariksihsidlihcdnaehsetahgnisol
10
Kira
hates
is
he
losing
death
childish
L
and
Note

Output

Kira is childish and he hates losing 

Input

12
iherehtolleh
5
HI
Ho
there
HeLLo
hello

Output

HI there HeLLo 

Note

In sample case 2 there may be multiple accepted outputs, "HI there HeLLo" and "HI there hello" you may output any of them.

题意:现在给出一个长度为n的文本串,又给出了m个单词,单词里面既有大写字母,也有小写字母。现在题中说的是,那个文本串是由给出的单词组成的,组成方式,是将单词的大写字母全部转成小写,然后再反转。现在要求输出组成这个文本串的单词。

题解:这个题可以逆向建一颗字典树,再找。这里给出Hash的做法,首先将每个单词的hash值算出来,然后再去字符串里面找,因为一定有一种组成方式满足题意,所以一定可以找的到。代码貌似是O(n^2)的复杂度,因为单词长度不会超过,每次找到了就break,复杂度就远远没有O(n^2)了。细节看代码。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=1e4+10;
const int mod=1e4+10;
const int inf=1e8;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
#define mid l+(r-l)/2
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI 3.14159265358979323846
int dir[4][2]= {0,-1,-1,0,0,1,1,0};
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
map<ll,string>q;///有没有大佬知道,为啥这里string换成char下面这句(q[sum]=s;)要报错
ll dp[maxn];
void print(int len)
{
    if(!len)
        return ;
    print(len-q[dp[len]].size());
    cout<<q[dp[len]]<<" ";
}
int main()
{
    char str[maxn],s[maxn];
    int seed=131;
    int n,m;
    scanf("%d%s%d",&n,str,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%s",s);
        int len=strlen(s);
        ll sum=0;
        for(int j=0;j<len;j++)
            sum=sum*seed+tolower(s[j]);///全部转化成小写,算hash值。
        q[sum]=s;///将字符串和hash值对应起来。
    }
    me(dp,-1);dp[0]=0;
    int len=strlen(str);
    for(int i=0;i<len;i++)
    {
        ll temp=0;
        for(int j=i;j>=0;j--)///反向找
        {
            temp=temp*seed+str[j];
            if(dp[j]!=-1&&q.count(temp))///dp[j]!=-1表示这个单词前面已经有了单词了,保证不间断,q.count(temp)确保有这个单词
            {
                dp[i+1]=temp;
                break ;
            }
        }
    }
    print(len);
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值