题目链接
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:
- Convert all letters of the sentence to lowercase.
- Reverse each of the words of the sentence individually.
- 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;
}