这题和今年南昌邀请网络预选赛M题很像啊,不过主串数量不是一个了
都是在主串中判断子串是不是属于主串的一个子序列
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;const int maxn = + ;
const int maxm = + ;
char s1[maxn], s2[maxm];
int Next[maxn][maxn][], last[], ans[maxn];
int n, m;
int main(){
// freopen("in.txt", "r", stdin); //输入文件里最后一行后要加回车,不然会死循环
scanf("%d%d", &n, &m);
getchar();
memset( ans, , sizeof(ans) );
memset( Next, -, sizeof(Next) );
for( int i=; i<n; i++ ){
char ch, tot = ;
while( (ch=getchar())!='\n' ){
if( ch>='A' && ch<='Z' ) ch += 'a'-'A';
s1[++tot] = ch;
}
s1[++tot] = ;
memset( last, , sizeof(last) );
for( int j=; j<tot; j++ ){
int id = s1[j]-'a';
for( int k=j-; k>=last[id]; k-- ) Next[i][k][id] = j; //Next数组存第i个主串k位置后第一个id字符所在的位置
last[id] = j;
}
}
for( int i=; i<m; i++ ){ //输入进来每个模式串
char ch, tot=;
while( (ch=getchar())!='\n' ){
if( ch>='A' && ch<='Z' ) ch += 'a'-'A';
s2[tot++] = ch;
}
s2[tot] = ;
for( int j=; j<n; j++ ){ //对每个主串进行匹配
int pos = ;
bool ok = ;
for( int k=; k<tot; k++ ){
int id = s2[k]-'a';
if( Next[j][pos][id]!=- ) pos = Next[j][pos][id]; //如果成功继续匹配下一字符
else{ //匹配不成功,即该字符在pos后没有出现,则break
ok = ;
break;
}
}
if( ok ) ans[j] ++; //每个主串成功匹配一个模式串后价值数+1
}
}
for( int i=; i<n; i++ ) printf("%d\n", ans[i]); //逐个输出 return ;
}