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) .
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
Recommend
题意:将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 */