HDU 1711 Number Sequence(kmp)

Description
给出两个序列a[1],a[2],…,a[n]和b[1],b[2],…,b[m],先要求出最小的k使得a[k]=b[1], a[k+1]=b[2],…,a[k+m-1]=b[m]
Input
第一行为用例组数,每组用例第一行为两个整数n和m表示两个序列的长度,第二行为n个整数表示a序列,第三行为m个整数表示b序列
Output
对于每组用例,如果存在k满足条件则输出最小的k,如果没有则输出-1
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
Solution
把序列中每个数看作一个字符,此题就转化为在文本串(a序列)中找模式串(b序列)了,这个问题显然可以用kmp算法求解,如果找到匹配标记后直接退出循环即可,如果最后没有标记说明没有匹配
Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 1111111 
int a[maxn],b[11111];
int la,lb;
int nex[1111111];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(nex,0,sizeof(nex));
        scanf("%d%d",&la,&lb);
        for(int i=0;i<la;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<lb;i++)
            scanf("%d",&b[i]);
        int flag=-1;
        for(int i=0,j=-1;i<=lb;i++,j++)//得到next数组 
        {
            nex[i]=j;
            while(~j&&b[i]!=b[j])
                j=nex[j];
        }
        for(int i=0,j=0;i<=la;i++,j++)
        {           
            if(j==lb)//找到匹配 
            {
                flag=i-lb+1;//K值 
                break;
            }
            while(~j&&a[i]!=b[j])
                j=nex[j];
        }
        printf("%d\n",flag);
    }
    return 0;
}

你可能感兴趣的:(HDU 1711 Number Sequence(kmp))