Codeforces Round #106 (Div. 2) 149/E E. Martian Strings

/*
  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; }

 

转载于:https://www.cnblogs.com/Roly/archive/2013/05/21/3091611.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值