题目链接:http://codeforces.com/problemset/problem/633/C
题目大意:给你一个长度为N的字符串,这个字符串是由一句完整的话 单词拆分开之后每个单词变小写并翻转的来的,现在给你这个长度为N的字符串,还给你他的原来的组成成分,你要还原这句话,其中有的单词可能是多余的
思路:因为后面比较的时候我们用的是反着来的单词,所以直接反着建立一颗字典树就可以了,相当于是数字序列进行比较的了,这个题目是保证一定有解的,
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=100005;
string text,p[maxn];
int tire[maxn<<4][26];
int ans[maxn>>3],val[maxn<<4];
int n,m;
int cnt,total;
bool ok;
void nsert(int x)
{
int pos=0;
for(int i=p[x].size()-1;i>=0;i--)
{
int id=tolower(p[x][i])-'a';
if(!tire[pos][id])
tire[pos][id]=cnt++;
cout<<tire[pos][id]<<" ";
pos=tire[pos][id];
}//cout<<pos<<"<-"<<endl;
//cout<<endl;
val[pos]=x;
//cout<<val[pos]<<endl;
}
void dfs(int len)
{
if(len==n-1)
{
for(int i=0;i<total;i++)
{
cout<<p[ans[i]]<<" ";
}
cout<<endl;
ok=true;
return ;
}
int pos=0;
for(int i=len+1;!ok&&i<n;i++)
{
int id=text[i]-'a';
pos=tire[pos][id];
if(!pos)
break;
if(val[pos])
{
ans[total++]=val[pos];
dfs(len+p[val[pos]].size());
total--;
}
}
}
int main()
{
cin>>n>>text>>m;
cnt=1;
for(int i=1;i<=m;i++)
{
cin>>p[i];
nsert(i);
}
dfs(-1);
return 0;
}