HDU Problem - 5918 Sequence I
阿新 • • 發佈:2018-12-28
Problem Description
Mr. Frog has two sequences and and a number p. He wants to know the number of positions q such that sequence is exactly the sequence where and .
Input
The first line contains only one integer , which indicates the number of test cases.Each test case contains three lines.The first line contains three space-separated integers and .The second line contains n integers .the third line contains m integers .
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
AC
- 在a陣列中匹配b,每次間隔p,如果每次間隔1的話,直接一個kmp就可以,但是間隔2以上就要列舉所有的區間進行kmp,要不然會漏掉
- 例如a陣列:1,1,2,2,3,3,b陣列:1, 2, 3 p = 2,如果只是從0開始跑kmp,只會得到1對應a陣列中下標為(0,2,4),但是(1,3,5)就漏掉了
- 所以在滿足可以構成M個數的前提下,保證所有的區間恰好都覆蓋
#include <iostream>
#include <stdio.h>
#include <map>
#include <vector>
#include <set>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 1000005
#define ll long long
using namespace std;
int a[N], b[N], pre[N];
void get_next(int m) {
int i = 0, j = -1;
pre[0] = -1;
while (i < m) {
if (b[i] == b[j] || j == -1)
pre[++i] = ++j;
else
j = pre[j];
}
}
int kmp(int start, int n, int m, int p) {
int ans = 0;
get_next(m);
int i = start, j = 0;
while (i < n) {
if (j == -1 || a[i] == b[j])
j++, i += p;
else
j = pre[j];
if (j == m)
ans++, j = pre[j];
}
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int t;
scanf("%d", &t);
int Case = 1;
while (t--) {
int n, m, 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;
// 列舉所有區間
for (int i = 0; i < p; ++i) {
// 保證構成M個數
if (i + m * p - p <= n - 1)
ans += kmp(i, n, m, p);
else
break;
}
printf("Case #%d: %d\n", Case++, ans);
}
return 0;
}