[CF314B](Sereja and Periods)

  • 题意

定义[x,n]为n个字符串x首尾相接

给你两个字符串w=[a,b],q=[c,d];

求一个数ans

使得[ans,q]为w的子串,并要求最大化ans

  • solution

暴力求解

就是aaaaaaaaa(b个a)中找有几个c

关键两点:

1.每个a是重复出现的

2.aa中可能还会出现关键字符(继续匹配),所以每个a串的匹配不是一样的,要么找循环节,要么像我一样仍然枚举b但加速匹配过程

考虑到字符串长度不大,让我们造两个数组cnt[..],next[..]

\(cnt_i\)表示从\(c_i\)(注意是c串)开始匹配
把a串匹配一遍后,匹配了几个c串

\(next_i\)表示\(c_i\)(同样是c串)开始匹配
把a串扫一遍后匹配到c串的哪一位

这里有点kmp的思路,即在模式串上记下一次从哪里开始匹配

那么我们从1扫到b
每次跳next,答案加cnt

next,cnt就能概括所有匹配情况,所以我们用next,cnt省略每个a串(每个a串从头扫到尾以匹配b串)的匹配过程

  • code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#define N 205
using namespace std;
string s1,s2;
int a,b;
int nxt[N],cnt[N];
int main(){
  scanf("%d%d",&a,&b);
  cin>>s1>>s2;
  for(int i=0;i<s2.size();i++){
     int pos=i;
     for(int r=0;r<s1.size();r++){
        if(s2[pos]==s1[r]){
          pos++;
          if(pos==s2.size())cnt[i]++,pos=0;
          }
        }
     nxt[i]=pos;
     }
  int ans=0;
  int poss=0;
  for(int i=1;i<=a;i++)ans+=cnt[poss],poss=nxt[poss];
  cout<<ans/b;
}
posted @ 2019-02-16 15:11  stepsys  阅读(187)  评论(0编辑  收藏  举报

*/