题目:http://acm.hdu.edu.cn/showproblem.php?pid=5918
题意:给定两个字符串A,B和一个数字p,求出A中有多少个间隔为p的连续字符串与B相同
输入说明:先输入测试的次数,每次测试输入三行,第一行为三个数,分别为n(字符串A的长度),m(字符串B的长度),p(间隔长度)
第二行输入数组A,第三行是数组B
题解:典型的kmp,就是要通过每次处理A,通过每次间隔p提取连续的数组进行和B配对,其他与kmp相同
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int value_a[1000050];
int value_b[1000050];
int value[1000050];
int nexton[1000050];
long long sum=0;
void getnext(int len)
{
int j=-1,i=0;
nexton[i]=j;
while(i<=len)
{
if(j==-1||value_b[i]==value_b[j])
{
i++;j++;nexton[i]=j;
}
else
{
j=nexton[j];
}
}
}
int kmp(int son,int father)
{
int i=0,j=0;
while(i<son&&j<father)
{
if(i==-1||value_b[i]==value[j])
{
i++;j++;
}
else
{
i=nexton[i];
}
if(i==son)
{
i=nexton[i];
sum++;
}
}
}
int main()
{
int t;
int n,m,k;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
scanf("%d %d %d",&n,&m,&k);
for(int j=0;j<n;j++)
{
scanf("%d",&value_a[j]);
}
for(int j=0;j<m;j++)
{
scanf("%d",&value_b[j]);
}
getnext(m);
sum=0;
for(int j=0;j<k;j++)//此处为处理,其余几乎为模板
{
int cnt=0;
for(int j1=0;j1*k+j<n;j1++)
{
value[cnt++]=value_a[j1*k+j];
}
if(cnt>=m)
{
kmp(m,cnt);
}
}
printf("Case #%d: %lld\n",i,sum);
}
return 0;
}