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+(m1)p where q+(m1)pn and q1 .
 

 

Input
The first line contains only one integer T100 , which indicates the number of test cases.

Each test case contains three lines.

The first line contains three space-separated integers 1n106,1m106 and 1p106 .

The second line contains n integers a1,a2,,an(1ai109) .

the third line contains m integers b1,b2,,bm(1bi109) .
 

 

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
 

 

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

 

posted @ 2017-09-04 23:35  hinata_hajime  阅读(155)  评论(0编辑  收藏  举报