Number Sequence
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 34658 Accepted Submission(s): 14405
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
题解:典型的KMP类型的题,只不过把字符串改为了数字串,看代码就明白了
AC代码:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e6+10;
int s1[maxn],s2[maxn],Next[maxn];
int T,N,M;
void GetNext(int *Next,int *s2)
{
Next[0]=Next[1]=0;
for(int i=1;i<M;i++)
{
int j=Next[i];
while(j && s2[j]!=s2[i]) j=Next[j];
Next[i+1]=s2[i]==s2[j]? j+1:1;
}
}
void GetFail()
{
int j=0;
for(int i=0;i<N;i++)
{
while(j && s1[i]!=s2[j]) j=Next[j];
if(s1[i]==s2[j]) j++;
if(j==M)
{
cout<<i+2-M<<endl;
return ;
}
}
cout<<-1<<endl;
}
int main()
{
cin>>T;
while(T--)
{
cin>>N>>M;
for(int i=0;i<N;i++)
cin>>s1[i];
for(int i=0;i<M;i++)
cin>>s2[i];
GetNext(Next,s2);
GetFail();
}
return 0;
}