kmp“看毛片”算法模板题

来源:互联网 发布:红包透视软件 编辑:程序博客网 时间:2024/04/24 15:22

kmp“看毛片”算法模板题

HDU1711


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

Source
HDU 2007-Spring Programming Contest

Recommend
lcy | We have carefully selected several similar problems for you: 1358 3336 1686 3746 1251

这个算法很不好理解,个人表示看了很久才略懂,然后找了这个题来做。大意是:给两个数列,在A数列中找到B数列,并输出第一次找到B数列的位置(从B数列第一个数开始的第一个位置),若找不到则输出-1。

这道题就是直接套kmp模板,用next【】数组来保存位移
如B数组为1 2 3 1 3 1 2 3 1 1 3
那么next为 1,1,1,2,1,2,3,4,5,2,1

代码

#include<cstdio>#include<iostream>#include<cstring>using namespace std;int wenben[1000005],moban[10005];int next1[10005];int n,m;void makenext(){    int k=1,q;    next1[1]=1;    for(q=2;q<=m;q++)    {        while(k>1&&moban[k]!=moban[q])            k=next1[k-1];        if(moban[k]==moban[q])            k++;        next1[q]=k;    }    return ;}void kmp(){    int k=1,q,ans=-1;    for(q=1;q<=n;q++)    {        while(k>1&&moban[k]!=wenben[q])            k=next1[k-1];        if(moban[k]==wenben[q])            k++;        if(k==m+1)        {            ans=q-m+1;            break;        }    }    printf("%d\n",ans);    return ;}int main(){    int t;    cin>>t;    while(t--)    {        cin>>n>>m;        for(int i=1;i<=n;i++)        cin>>wenben[i];        for(int i=1;i<=m;i++)        cin>>moban[i];        makenext();        kmp();    }    return 0;}
0 0
原创粉丝点击