【HDU-1711】解题报告(KMP模板题,字符串hash)

原始题目

Number Sequence

  • Time Limit: 10000/5000 MS (Java/Others)
  • Memory Limit: 32768/32768 K (Java/Others)
  • Total Submission(s): 39142
  • Accepted Submission(s): 16165

Problem Description

Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 ≤ M ≤ 10000, 1 ≤ N ≤ 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one.

Input

The first line of input is a number T which indicate the number of cases. Each case contains three lines. The first line is two numbers N and M (1 ≤ M ≤ 10000, 1 ≤ N ≤ 1000000). The second line contains N integers which indicate a[1], a[2], ...... , a[N]. The third line contains M integers which indicate b[1], b[2], ...... , b[M]. All integers are in the range of [-1000000, 1000000].

Output

For each test case, you should output one line which only contain K described above. If no such K exists, output -1 instead.

Sample Input

2
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 1 3
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 2 1

Sample Output

6
-1

Source

HDU 2007-Spring Programming Contest

Recommend

lcy

题目大意

  • 给定一个数字串和一个模式串,输出最早匹配的位置,没有输出-1。

解题思路

  • KMP把字符匹配改成int即可。

解题代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <vector>
#define pb push_back
#define mp make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define PI acos((double)-1)
#define E exp(double(1))
#define K 1000000+9
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define ms(x,a) memset((x),(a),sizeof(a))
int nt[10006];
int a[K],b[10005],n,m;
//参数为模板串和next数组
//字符串均从下标0开始
void kmp_next(int *T,int *nt)
{
nt[0]=0;
for(int i=1,j=0;i<m;i++)
{
while(j&&T[i]!=T[j])j=nt[j-1];
if(T[i]==T[j])j++;
nt[i]=j;
}
}
int kmp(int *S,int *T,int *nt)
{
kmp_next(T,nt);
int ans=0;
//n //m
for(int i=0,j=0;i<n;i++)
{
while(j&&S[i]!=T[j])j=nt[j-1];
if(S[i]==T[j])j++;
if(j==m){
// ans++;
return i-m+2;
}

}
return -1;
}
int main(void)
{
ios::sync_with_stdio(false);
int t;cin>>t;
while(t--)
{
cin>>n>>m;
rep(i,0,n) cin>>a[i];
rep(i,0,m) cin>>b[i];
cout<< kmp(a,b,nt)<<endl;
}

return 0;
}
//1 2 1 2 3 1 2 3 1 3 2 1 2 3 1 2 3

收获与反思

  • 单模匹配考虑KMP,熟悉模板和算法。