搏一搏,单车变摩托!
虽然是KMP但是可以暴力水过。
#include <cstdio>
#include <cstring>
const int maxn = 1000000 + 5;
const int maxm = 1000000 + 5;
int a[maxn];
int b[maxm];
int main(int argc, char const *argv[]) {
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++) {
int n, m, p;
scanf("%d%d%d", &n, &m, &p);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= m; i++) {
scanf("%d", &b[i]);
}
int cnt = 0;
for (int q = 1; q + (m - 1) * p <= n; q++) {
bool ok = true;
for (int i = 0, j = 1; i < m && j <= m; i++, j++) {
if (a[q+i*p] != b[j]) {
ok = false;
break;
}
}
if (ok) {
cnt++;
}
}
printf("Case #%d: %d\n", t, cnt);
}
return 0;
}
KMP解法:枚举位置q,然后计算匹配到的个数。
#include <cstdio>
const int maxn = 1000000 + 5;
const int maxm = 1000000 + 5;
int a[maxn];
int b[maxm];
int s[maxn];
int next[maxm];
int n, m;
void get_next() {
int k = 0;
next[0] = 0;
for (int q = 1; q < m; q++) {
while (k > 0 && b[q] != b[k]) {
k = next[k-1];
}
if (b[q] == b[k]) {
k++;
}
next[q] = k;
}
}
int kmp(int len) {
int cnt = 0;
int k = 0;
for (int p = 0; p < len; p++) {
while (k > 0 && s[p] != b[k]) {
k = next[k-1];
}
if (s[p] == b[k]) {
k++;
}
if (k == m) {
cnt++;
k = next[k-1];
}
}
return cnt;
}
int main() {
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++) {
int p;
scanf("%d%d%d", &n, &m, &p);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (int i = 0; i < m; i++) {
scanf("%d", &b[i]);
}
int ans = 0;
get_next();
for (int i = 0; i < p; i++) {
int len = 0;
for (int j = i; j < n; j += p) {
s[len++] = a[j];
}
if (len < m) {
break;
}
ans += kmp(len);
}
printf("Case #%d: %d\n", t, ans);
}
return 0;
}