https://loj.ac/problem/10053
题目描述
给出一个字典和一个句子,求最多能理解到这句话的第几个位置(前缀)。
思路
字典树,自然如同它的名字一样,可以用来处理字典的问题。首先显然我们可以建一棵字典树,接下来我们明确我们求的是能理解的前缀,而不是总长度,因此不是多字符串匹配,不用(AC)自动机。由于字典中的单词可能会有嵌套,我们考虑用(f[i])表示我们是否可以匹配到这一位,所以我们可以从每一位可以匹配的地方出发,进行字符串匹配,再记录答案。而最大的(i)满足(f[i]=1)就是答案。
代码
#include <bits/stdc++.h>
using namespace std;
int ch[1000005][30],tot;
char s[30],ss[1000005];
bool ed[1000005],f[1000005];
void insert(char *s)
{
int u=1,len=strlen(s);
for(int i=0;i<len;i++)
{
int c=s[i]-'a';
if(!ch[u][c])ch[u][c]=++tot;
u=ch[u][c];
}
ed[u]=1;
}
int find(char *s)
{
int u=1,len=strlen(s+1);
int ans=0;
memset(f,0,sizeof(f));
f[0]=1;
for(int i=0;i<=len;i++)
{
if(!f[i])continue ;
else ans=i;
u=1;
for(int j=i+1;j<=len;j++)
{
// cout<<j<<' '<<s[j]<<endl;
int c=s[j]-'a';
if(!ch[u][c])break ;
u=ch[u][c];
if(ed[u])f[j]=1;
}
}
return ans;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
tot=1;
for(int i=1;i<=n;i++)
{
scanf(" %s",s);
insert(s);
}
for(int i=1;i<=m;i++)
{
scanf(" %s",ss+1);
printf("%d
",find(ss));
}
return 0;
}