题不知道哪个平台有,根据王道机试指南的题:
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
实现:
#include <cstdio>
//使用KMP进行字符匹配
const int MAXN=1000000;
const int MAXM=10000;
int nexttable[MAXM];
int parttern[MAXM];
int text[MAXN];
//创建next数组的函数,对模式串计算next
void getNext(int m){ //需要模式串的长度
int j=0;
nexttable[j]=-1;//初始化回溯标记
int i=nexttable[j];
while(j<m){ //对每位进行判断
//i为-1的时候说明重新匹配需要递增
if(i==-1||parttern[i]==parttern[j]){
i++;
j++;
nexttable[j]=i;
}
else{
i=nexttable[i];
}
}
}
//kmp的函数,返回匹配位置
int kmp(int n,int m){//n为主串长度,m为模式串长度
getNext(m);
int i=0,j=0;
while(i<n&&j<m){
if(j==-1||text[i]==parttern[j]){//j=-1即从头匹配
i++;
j++;
}
else{
j=nexttable[j];
}
}
if(j==m){//是否匹配成功
return i-j+1;
}
else{
return -1;
}
}
//main函数,满足题意
int main(){
int casenum;
scanf("%d",&casenum);
while(casenum--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&text[i]);
}
for(int i=0;i<m;i++){
scanf("%d",&parttern[i]);
}
int pos=kmp(n,m);
printf("%d\n",pos);
}
return 0;
}