A - Number Sequence
Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit Status Practice HDU 1711
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
题目大意:
给你一个长度为n和长度为m的串,然后让你求出这个长度为m的串第一次在长度为n的串中出现的下标是什么(当然是完全匹配后的),如果有
多个地方出现了这个长度为m的串,那我们就输出最小的下标编号。
解题思路:
直接上kmp,先对模式串通过O(m)的时间复杂度,计算出next[],然后通过kmp找到找到第一次匹配成功的模式串在文本串中的位置,然后输出
t1-len2+1就OK了。
代码:
1 # include<cstdio> 2 # include<iostream> 3 # include<cstring> 4 5 using namespace std; 6 7 8 int a[1000004]; 9 int b[10004]; 10 int nxt[10004]; 11 int n,m; 12 13 void get_next() 14 { 15 int len = m; 16 int t1 = 0, t2; 17 t2 = nxt[0] = -1; 18 while ( t1<len ) 19 { 20 if ( t2==-1||b[t1]==b[t2] ) 21 { 22 t1++;t2++; 23 nxt[t1] = t2; 24 } 25 else 26 t2 = nxt[t2]; 27 } 28 } 29 30 31 int kmp ( int *a,int *b ) 32 { 33 int len1 = n, len2 = m; 34 int t1 = 0,t2 = 0; 35 while ( t1<len1&&t2<len2 ) 36 { 37 if ( t2==-1||a[t1]==b[t2] ) 38 { 39 t1++;t2++; 40 } 41 else 42 t2 = nxt[t2]; 43 } 44 if ( t2==len2 ) 45 return t1-t2+1; 46 else 47 return -1; 48 } 49 50 51 int main(void) 52 { 53 int t;scanf("%d",&t); 54 while ( t-- ) 55 { 56 scanf("%d%d",&n,&m); 57 for ( int i = 0;i < n;i++ ) 58 scanf("%d",&a[i]); 59 for ( int j = 0;j < m;j++ ) 60 scanf("%d",&b[j]); 61 get_next(); 62 int ans = kmp(a,b); 63 printf("%d\n",ans); 64 } 65 66 67 68 return 0; 69 }