题目链接·:http://acm.hdu.edu.cn/showproblem.php?pid=5918
求
问从a串中每隔p取数字,有多少个可与b串匹配
思路:用kmp可计算连续的a串中有多少个b串,可将每p个数字取出组成连续的新串,共可取出p条新串,对每条新串kmp再求和即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=1e6+10;
int a[maxn];//主串
int Next[maxn];
int c[maxn];
int b[maxn];
int t,n,m,p,anss,ans;
void getNext()
{
int i=0,j=-1;
Next[0]=-1;
while(i<m)
{
if(j==-1||b[i]==b[j])
{
i++;
j++;
Next[i]=j;
}
else
j=Next[j];
}
}
void kmp(int s[],int len) {
int i,k=0,ret=0;
for (i=0;i<len;i++) {
while (k>0&&b[k]!=s[i]) k=Next[k];
if (b[k]==s[i]) k++;
if (k==m) ans++,k=Next[k];
}
}
int main()
{
scanf("%d",&t);
int f=1;
while(t--)
{
ans=0;
scanf("%d%d%d",&n,&m,&p);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<m;i++)
scanf("%d",&b[i]);
getNext();
for(int i=0;i<p&&i<n;i++)
{
// memset(c,0,sizeof(c));加上超时
int j;
for(j=0;i+j*p<n;j++)
c[j]=a[i+j*p];
kmp(c,j);
}
printf("Case #%d: %d\n",f++,ans);
}
return 0;
}