HDU 5918 Sequence I (KMP)

Sequence I

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2330    Accepted Submission(s): 874

Problem Description

Mr. Frog has two sequences a1,a2,?,an

and b1,b2,?,bm

and a number p. He wants to know the number of positions q such that sequence b1,b2,?,bm

is exactly the sequence aq,aq+p,aq+2p,?,aq+(m?1)p

where q+(m?1)p≤n

and q≥1

.

Input

The first line contains only one integer T≤100

, which indicates the number of test cases.

Each test case contains three lines.

The first line contains three space-separated integers 1≤n≤106,1≤m≤106

and 1≤p≤106

.

The second line contains n integers a1,a2,?,an(1≤ai≤109)

.

the third line contains m integers b1,b2,?,bm(1≤bi≤109)

.

Output

For each test case, output one line “Case #x: y”, where x is the case number (starting from 1) and y is the number of valid q’s.

Sample Input

2
6 3 1
1 2 3 1 2 3
1 2 3
6 3 2
1 3 2 2 3 1
1 2 3

Sample Output

Case #1: 2
Case #2: 1

Source

2016中国大学生程序设计竞赛(长春)-重现赛

Recommend

wange2014   |   We have carefully selected several similar problems for you:  6193 6192 6191 6190 6189

题意:将bn与an数组每隔p项进行匹配,bn为模式串,an为主串,问有多少种匹配

分析:   每隔p项进行匹配的时候,第一次匹配 0 p 2p 3p 4p

第二次匹配 1 p+1 2p+1 3p+1 4p+1

那么进行p次对主串的扫描完成所有的匹配

代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

const int N = 1000002;
int Next[N];
int S[N], T[N];
int slen, tlen;//注意每次一定要计算长度
   int n,m,p;
void getNext()
{
    int j, k;
    j = 0; k = -1; Next[0] = -1;
    while(j < tlen)
        if(k == -1 || T[j] == T[k])
            Next[++j] = ++k;
        else
            k = Next[k];

}
int KMP_Count()
{
    int ans = 0;
    int i, j = 0;

    if(slen == 1 && tlen == 1)
    {
        if(S[0] == T[0])
            return 1;
        else
            return 0;
    }
    getNext();
  for(int k=0;k<p;k++){
        j=0;
    for(i = k; i < slen; i=i+p)
    {
        while(j>=0 && S[i] != T[j])
            j = Next[j];
        if(j==-1||S[i] == T[j])
            j++;
        if(j == tlen)
        {
            ans++;
            j = Next[j];
        }
    }
  }
    return ans;
}
int main()
{

    int TT,Case=0;
    scanf("%d",&TT);
    while(TT--)
    {
        Case++;
        scanf("%d%d%d",&n,&m,&p);
        for(int i=0;i<n;i++)scanf("%d",&S[i]);
        for(int i=0;i<m;i++)scanf("%d",&T[i]);
        slen=n;
        tlen=m;;
        printf("Case #%d: %d\n",Case,KMP_Count());
    }
    return 0;
}
/*10
3 1 5
1 1 1
1
Case #1: 1
*/
时间: 2024-10-06 17:29:51

HDU 5918 Sequence I (KMP)的相关文章

【hdu 5918】Sequence I(KMP)

给定两个数字序列,求a序列中每隔p个构成的p+1个序列中共能匹配多少个b序列. 例如1 1 2 2 3 3 每隔1个的序列有两个1 2 3 kmp,匹配时每次主串往前p个,枚举1到p为起点. 题目 #include<bits/stdc++.h> #define N 1000005 int t,n,m,p; int nex[N]; int a[N],b[N]; using namespace std; void getNext(){ int i=0,k=-1; nex[0]=k; while(b

hdu 2087-剪花布条(KMP)

题意: 求文本串最多可以分成几个模式串. 分析: KMP #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype&g

hdu 2594-Simpsons’ Hidden Talents(KMP)

题意: 给你两个串a,b,求既是a的前缀又是b的后缀的最长子串的长度. 分析: 很自然的想到把两个串连接起来,根据KMP的性质求即可 #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #includ

hdu 2203亲和串 (kmp)

#include<cstdio>#include<iostream>#include<cstring>#include<string>using namespace std;int Next[100005];void getnext(const char *W,int *next){    int j=0,k=-1;    next[0]=-1;    while(!j || W[j]!='\0')    {        if(k==-1 || W[j]=

HDU 3746 Cyclic Nacklace(KMP)

KMP求最短循环节的应用 //2100 KB 218 ms #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define M 100000+1000 char str[M]; int next2[M]; int len; void getnext() { len=strlen(str); int i=0,j; j=n

HDU 2203 亲和串(kmp)

Problem Description 人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考,因为他在很小的时候就知道亲和串如何判断了,但是发现,现在长大了却不知道怎么去判断亲和串了,于是他只好又再一次来请教聪明且乐于助人的你来解决这个问题. 亲和串的定义是这样的:给定两个字符串s1和s2,如果能通过s1循环移位,使s2包含在s1中,那么我们就说s2 是s1的亲和串. Input 本题有多组测试数据,每组数据的第一行包含输入字符串s1,第二

hdu 2160 Sequence one(DFS)

1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <cstdio> 5 #include <memory.h> 6 using namespace std; 7 #define MAXN 20002 8 9 10 //适用于正整数 11 template <class T> 12 inline void scan_d(T &r

HDU 2594 Simpsons’ Hidden Talents (KMP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2594 这题直接用KMP算法就可以做出来,不过我还尝试了用扩展的kmp,这题用扩展的KMP效率没那么高. KMP算法: #include<stdio.h> #include<iostream> #include<string.h> using namespace std; int next[50001]; char p[50000],s[50000]; void getnex

hdu 3374 String Problem (kmp+最大最小表示法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小表示的方法: (1)  利用两个指针p1, p2.初始化时p1指向s[0], p2指向s[1]. (2)  k = 0开始,检验s[p1+k] 与 s[p2+k] 对应的字符是否相等,如果相等则k++,一直下去,直到找到第一个不同,(若k试了一个字符串的长度也没找到不同,则那个位置就是最小表示位置,