题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711
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
题目翻译:
给定两个数字序列 a[]
和 b[]
,b[]
有可能整体作为一个连续子序列出现在了 a[]
中,现在请你找出 b[]
在 a[]
中第一次出现的位置(起始位置从 1 开始计数),如果一次都没有出现,请输出 -1。
输入格式
第一行包含一个数字 T,表示测试用例的个数。
对于每组测试用例,第一行包含两个数字 n m ( 1<= n <= 1000000, 1 <= m <= 10000 ),表示 a[]
和 b[]
的长度。
接下来的一行包括 n 个数字,依次表示 a[1], a[2], a[3] ... a[n]
,-1000000 <= a[i] <= 1000000
接下来的一行包括 m 个数字,依次表示 b[1], b[2], b[3] ... b[m]
,-1000000 <= b[i] <= 1000000
输出格式
对于每组数据输出一行,请输出 b[]
整体作为一个连续子序列在 a[]
中的首次出现位置的起始下标,如果一次都没有完整出现,输出 -1。
算是一道kmp入门的模板题,基本上没变,不过有个坑点,用cin读入时要关流,不然会超时。
#include <iostream>
using namespace std;
const int maxn=1e6+5;
int n,m;
int a[maxn],b[maxn];
int nxt[100005];
void getnext(){
nxt[0]=nxt[1]=0;
for(int i = 1;i<m;++i){
int j = nxt[i];
while(j&&b[i]!=b[j]) j=nxt[j];
nxt[i+1]=b[i]==b[j]?j+1:0;
}
}
void kmp(){
getnext();
int j = 0,i;
for(i = 0;i<n;++i){
while(j&&a[i]!=b[j]) j=nxt[j];
if(a[i]==b[j]) j++;
if(j==m) break;
}
if(j==m) printf("%d\n",i-m+2);
else printf("-1\n");
}
int main(int argc, char** argv) {
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i = 0;i<n;++i) scanf("%d",&a[i]);
for(int i = 0;i<m;++i) scanf("%d",&b[i]);
kmp();
}
return 0;
}