不懂KMP可以看這篇文章哦,我在線會回的
題目鏈接
題意:
給出兩個數字序列 : a[1], a[2], ...... , a[N], 和 b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). 你的任務是找到一個數字K滿足: a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. 如果有多個K滿足題意,請你輸出最小的那個K。
輸入
第一行是一個數字T代表有T組測試數據. 每組測試數據有三行. 第一行是兩個數字 N and M (1 <= M <= 10000, 1 <= N <= 1000000). 第二行包括N個整數代表a[1], a[2], ...... , a[N]. 第三行包括M個整數代表b[1], b[2], ...... , b[M]. 所有數字的範圍在[-1000000, 1000000]之間。
輸出
對於每組測試數據, 你應該輸出一行答案。代表K, 如果沒有符合題意的K,那麼輸出-1。
這是一道模板題,希望做題的時候可以裸敲不要看模板,這樣可以更深度的理解什麼是KMP算法。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN=1e6+5;
int N, M;
int a[maxN], b[maxN];
void cal_next(int *next)
{
next[1]=0;
int k = 0;
for(int i=2; i<=M; i++)
{
while(k>0 && b[k+1]!=b[i])
{
k=next[k];
}
if(b[k+1] == b[i]) k++;
next[i]=k;
}
}
int KMP()
{
int *next = new int[M+1];
cal_next(next);
int k = 0;
for(int i=1; i<=N; i++)
{
while(k>0 && b[k+1]!=a[i])
{
k=next[k];
}
if(b[k+1] == a[i]) k++;
if(k == M) return i-M+1;
}
return -1;
}
int main()
{
int T; scanf("%d", &T);
while(T--)
{
scanf("%d%d", &N, &M);
for(int i=1; i<=N; i++) scanf("%d", &a[i]);
for(int i=1; i<=M; i++) scanf("%d", &b[i]);
printf("%d\n", KMP());
}
return 0;
}