思路:Tire树存单词,然后每段话在Trie树上搜索。vis[i]=1表示这段话1到i能被识别,搜完后vis[i]=1最大的i就是答案,可以确保i之前的能被识别,否则dfs无法到达i。
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXLEN=1000005;
int ch[20*10*26+5][26],val[20*10*26+5],vis[MAXLEN],np=0,rt=0;
char s[MAXLEN];
int idx(char c)
{
if(c>='A'&&c<='Z') return c-'A';
return c-'a'+26;
}
void insert(int &now,char *s,int i)
{
if(!now) now=++np;
if(s[i]=='\0')
{
val[now]=1;
return;
}
insert(ch[now][idx(s[i])],s,i+1);
}
void dfs(int now,int pos)
{
int d=idx(s[pos]);
if(val[now]&&!vis[pos-1])
{
vis[pos-1]=1;
dfs(rt,pos);
}
if(ch[now][d]) dfs(ch[now][d],pos+1);
}
int main()
{
int N,M,len;
scanf("%d%d",&N,&M);
while(N--)
{
scanf("%s",s);
insert(rt,s,0);
}
while(M--)
{
scanf("%s",s+1);
memset(vis,0,sizeof(vis));
len=strlen(s+1);
dfs(rt,1);
while(len)
{
if(vis[len]) break;
len--;
}
printf("%d\n",len);
}
return 0;
}