Sequence I
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 216 Accepted Submission(s): 93
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
题意:给定数组 a1...an ,b1...bm, 以及间隔 d,问 a 中使得存在 aq ,aq+d , aq+2d...aq+(m-1)d 和 b数组相等的 q 有多少个?
题解:标准解法是 KMP,我这双重循环强行水了过去..
#include <bits/stdc++.h> using namespace std; const int N = 1000005; int a[N],b[N]; int main() { int tcase,t=1; scanf("%d",&tcase); while(tcase--){ int n,m,k; scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<=m;i++){ scanf("%d",&b[i]); } if(m>n) { printf("Case #%d: %d\n",t++,0); continue; } int ans = 0; for(int i=1;i<=n;i++){ if(a[i]!=b[1]) continue; int idx = 1; for(int j=i;j<=n;j+=k){ if(a[j]==b[idx]){ idx++; } else break; if(idx==m+1){ ans++;break; } } } printf("Case #%d: %d\n",t++,ans); } return 0; }
KMP解法
#include <iostream> #include <cstring> #include <stdio.h> #include <stdlib.h> #include <algorithm> using namespace std; const int N = 1000002; int Next[N]; int A[N],S[N], T[N]; int slen, tlen; 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]; } /* 返回模式串在主串S中出现的次数 */ 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; } for(i = 0; i < slen; i++) { while(j > 0 && S[i] != T[j]) j = Next[j]; if(S[i] == T[j]) j++; if(j == tlen) { ans++; j = Next[j]; } } return ans; } int main() { int tcase,t=1; scanf("%d",&tcase); while(tcase--) { int n,k; scanf("%d%d%d",&n,&tlen,&k); memset(T,0,sizeof(T)); for(int i=0;i<n;i++) scanf("%d",&A[i]); for(int i=0;i<tlen;i++) scanf("%d",&T[i]); int ans = 0; getNext(); for(int i=0;i<k;i++){ ///枚举起点 slen = 0; for(int j = i;i+(tlen-1)*k<n&&j<n;j+=k){ S[slen++] = A[j]; } if(slen<tlen) continue; /*for(int j=0;j<slen;j++){ printf("%d ",S[j]); }*/ ans+=KMP_Count(); } printf("Case #%d: %d\n",t++,ans); } return 0; }