• HDU 1711 Number Sequence 【KMP应用 求成功匹配子串的最小下标】


    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1711

    Number Sequence

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


    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

    题意概括:

    给出一串主串,一串子串;

    求成功匹配到子串的最小下标;

    解题思路:

    KMP的应用,稍微变形,匹配到子串就跳出来输出。

    AC code:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 #define INF 0x3f3f3f3f
     7 using namespace std;
     8 const int MAXN = 1e6+10;
     9 const int MAXM = 1e4+10;
    10 int W[MAXM], T[MAXN];
    11 int wlen, tlen;
    12 int nxt[MAXM];
    13 
    14 void get_nxt()
    15 {
    16     int j, k;
    17     j = 0;
    18     k = -1;
    19     nxt[0] = -1;
    20     while(j < wlen){
    21         if(k == -1 || W[j] == W[k]){
    22             nxt[++j] = ++k;
    23         }
    24         else k = nxt[k];
    25     }
    26 }
    27 
    28 int KMP_index()
    29 {
    30     int i = 0, j = 0;
    31     get_nxt();
    32 
    33     while( i < tlen && j < wlen){
    34         if(j == -1 || T[i] == W[j]){
    35             i++;
    36             j++;
    37         }
    38         else j = nxt[j];
    39     }
    40     if(j == wlen) return i-wlen+1;
    41     else return -1;
    42 }
    43 
    44 int main()
    45 {
    46     int T_case, N, M;
    47     scanf("%d", &T_case);
    48     while(T_case--)
    49     {
    50         scanf("%d%d", &N, &M);
    51         wlen = M, tlen = N;
    52         for(int i = 0; i < N; i++)
    53             scanf("%d", &T[i]);
    54         for(int j = 0; j < M; j++)
    55             scanf("%d", &W[j]);
    56 
    57         printf("%d
    ", KMP_index());
    58     }
    59     return 0;
    60 }
    View Code
  • 相关阅读:
    hdu 1754 线段树 注意线段树节点的设计 求什么,设什么
    hdu 4015 概率题
    poj 1950 回溯
    最大上升子序列
    JVM学习博客
    2012
    i am alone at a crossroads
    易知难
    牢骚。。
    something
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10020540.html
Copyright © 2020-2023  润新知