Number Sequence 【HDU - 1711】【KMP模板】

不懂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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章