/*
http://codeforces.com/problemset/problem/149/E
KMP结合动态规划的思想,正向匹配一边,l[]数组保存的是对于匹配串的每一个位置在模式串能匹配的最左边,也就是首次匹配的位置
逆序再匹配一次,逆向信息保存r[]数组。
再枚举l[i]+r[len-i]
*/
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const int maxn = 1005;
const int inf = maxn*maxn+1;
int next[maxn];
char word[maxn];
char test[maxn*maxn];
char test_reverse[maxn*maxn];
int l[maxn],r[maxn];
void getnext(char str[]){
int i = 0,j = -1;
int len = (int)strlen(str);
next[0] = -1;
while(i < len){
if(j == -1 || str[i] == str[j]){
++i,++j;
if(str[i] == str[j])
next[i] = next[j];
else
next[i] = j;
}
else
j = next[j];
}
}
void kmp(char str[],char pat[],int dp[]){
int i = 0,j = 0;
getnext(pat);
int len_str = (int)strlen(str);
int len_pat = (int)strlen(pat);
while(i < len_str&&j < len_pat){
if(j == -1 || str[i] == pat[j]){
i++;
j++;
dp[j] = min(dp[j],i);
}
else
j = next[j];
if(j == len_pat)
j = next[j];
}
}
void init(int len){
l[0] = 0,r[0] = 0;
for(int i = 1;i <= len;i++){
l[i] = inf;
r[i] = inf;
}
}
int main(){
while(~scanf("%s",test)){
int len = (int)strlen(test);
for(int i=0;i<len;i++)
test_reverse[i]=test[len-1-i];
int m;
scanf("%d",&m);
int ans = 0;
while(m--){
scanf("%s",word);
int len_word = (int)strlen(word);
if(len_word==1) continue;
init(len_word);
kmp(test,word,l);
reverse(word, word+strlen(word));
kmp(test_reverse, word, r);
//for(int i = 0;i < strlen(word);i++)
// printf("%d %d\n",l[i],r[i]);
for(int i = 1;i <= len_word;i++){
if(l[i] + r[len_word - i] <= len){
ans++;
break;
}
}
}
printf("%d\n",ans);
}
return 0;
}
Codeforces Round #106 (Div. 2) 149/E E. Martian Strings
最新推荐文章于 2022-11-22 23:15:14 发布