记
f[i]
f
[
i
]
为文章中以第i个字符结尾的内容能否被理解
那么对于每篇文章最大的
i
i
即为答案
把单词集合全部插入Trie中,初始化
每当找到一个i使
f[i]=true
f
[
i
]
=
t
r
u
e
就开始在Trie中查询文章中i为起点的后文, 若查询过程中 找到一个叶子结点,即找到一个单词,记该位置为j,
f[j]=true
f
[
j
]
=
t
r
u
e
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define Max(_A,_B) (_A>_B?_A:_B)
#define Min(_A,_B) (_A<_B?_A:_B)
int read(){
int s = 0;bool f = 1;char c = getchar();
while(c > '9' || c < '0'){if(c == '-') f = 0; c = getchar();}
while(c >= '0' && c <= '9') {
s = s * 10 + c - '0';
c = getchar();
}
return f == 1 ? s : -s;
}
const int maxn = 217, maxm = 1048579;
int n, m;
bool f[maxm]; //f[i]表示前i个字母组成的串 能否被理解
char s[maxm];
struct Trie{
int ch[maxn][26], cnt[maxn], tot;
void init() {
memset(ch, -1, sizeof(ch));
memset(cnt, 0, sizeof(cnt));
tot = 0;
}
void insert(char *str) {
int p = 0;
for(int i = 0; str[i]; ++i) {
if(ch[p][str[i] - 'a'] == -1) ch[p][str[i] - 'a'] = ++tot;
p = ch[p][str[i] - 'a'];
}
cnt[p]++;
}
void sol(char *str) {
int p, j, len = strlen(str);
int ans = 0;
memset(f, 0, sizeof(f));
f[0] = true;
for(int i = 0; i <= len; i++) {
if(f[i]) { //插入后文
p = 0;
ans = i;
for(int j = i; j <= len; j++) {
if(cnt[p]) f[j] = true;
p = ch[p][str[j] - 'a'];
if(p == -1 || j == len) break;
}
}
}
printf("%d\n", ans);
}
}trie;
int main() {
n = read(), m = read();
trie.init();
while(n--) {
scanf("%s", s); trie.insert(s);
}
while(m--) {
scanf("%s", s); trie.sol(s);
}
return 0;
}