zoukankan      html  css  js  c++  java
  • HDU1711(KMP)

    Number Sequence

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 22739    Accepted Submission(s): 9727


    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

     
     1 //2016.10.7
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 
     6 using namespace std;
     7 
     8 const int inf = 0x3f3f3f3f;
     9 int a[1000005], b[10005], nex[10005];
    10 
    11 int kmp(int a[], int b[])
    12 {
    13     int ans = 0;
    14     nex[0] = -1;
    15     for(int i = 0, fail = -1; b[i] != inf;)//求nex数组, fail为失配指针
    16     {
    17         if(fail==-1 || b[i] == b[fail])
    18         {
    19             i++, fail++;
    20             nex[i] = fail;
    21         }else fail = nex[fail];
    22     }
    23     int i = 0, j = 0;
    24     for(; a[i] != inf; i++, j++)
    25     {
    26         if(j != -1 && b[j] == inf)return i-j+1;
    27         while(j != -1 && a[i] != b[j])j = nex[j];
    28     }
    29     if(b[j] == inf)return i-j+1;
    30     return -1;
    31 }
    32 
    33 int main()
    34 {
    35     int T, n, m;
    36     scanf("%d", &T);
    37     while(T--)
    38     {
    39         scanf("%d%d", &n, &m);
    40         for(int i = 0; i < n; i++)scanf("%d", &a[i]);
    41         for(int i = 0; i < m; i++)scanf("%d", &b[i]);
    42         a[n] = b[m] = inf;//设置截止符号
    43         printf("%d
    ", kmp(a, b));
    44     }
    45 
    46     return 0;
    47 }
  • 相关阅读:
    C++基类的析构函数定义为虚函数的原因
    android的学习网站
    QT显示url图片
    Ubuntu安装JDK
    linux下打包压缩和解压命令
    嵌入式目录
    QT pri 文件的作用
    QT pro文件详细写法+实例
    Computer(树的直径做法)
    树的直径
  • 原文地址:https://www.cnblogs.com/Penn000/p/5936700.html
Copyright © 2011-2022 走看看