zoukankan      html  css  js  c++  java
  • H

    The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names to their newly-born babies. They seek the name, and at the same time seek the fame. In order to escape from such boring job, the innovative little cat works out an easy but fantastic algorithm: 

    Step1. Connect the father's name and the mother's name, to a new string S. 
    Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S). 

    Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:) 

    Input

    The input contains a number of test cases. Each test case occupies a single line that contains the string S described above. 

    Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000. 

    Output

    For each test case, output a single line with integer numbers in increasing order, denoting the possible length of the new baby's name.

    Sample Input

    ababcababababcabab
    aaaaa
    

    Sample Output

    2 4 9 18
    1 2 3 4 5
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstring>
    using namespace std;
    #define MAXN 400001
    typedef long long LL;
    /*
    真正理解Next[]数组的含义
    Next[j] = k的含义是
    在数组里0-k的前缀和k-j+1-k的后缀相同,k是前j-1个元素里最大的相同前缀后缀长度
    
    那么题目要求求出所有相同前缀后缀长度,显然字符串总长度是一个解
    由Next[]数组的定义,Next[len]也是一个解(如果有解)——如果Next[len]==0显然说明无解
    那么通过递归的思想继续求更小的解:由于Next[len]==k那么说明 其他解如果存在 只能在[0,k]和 
    [len-k+1,len]中产生,而由于他们完全相同可以只考虑其中一个,比如[0,k]
    此时问题的形式是求一个序列所有前缀后缀 所以可以递归求解
    */
    char s[MAXN];
    int Next[MAXN];
    void kmp_pre(int m)
    {
        int j,k;
        j = 0;k = Next[0] = -1;
        while(j<m)
        {
            if(k==-1||s[j]==s[k])
                Next[++j] = ++k;
            else
                k = Next[k];
        }
    }
    void Print(int tmp)
    {
        if(Next[tmp])
        {
            Print(Next[tmp]);
            printf("%d ",Next[tmp]);
        }
    }
    int main()
    {
        while(scanf("%s",s)!=EOF)
        {
            int l = strlen(s);
            kmp_pre(l);
            int tmp = l;
            Print(tmp);
            printf("%d
    ",l);
        }
    }
  • 相关阅读:
    第二周
    第一周
    构建之法阅读笔记之三
    冲刺一(10)
    冲刺一(9)
    用户模板和用户场景
    冲刺一(8)
    第10周总结
    冲刺一(7)
    冲刺一(6)
  • 原文地址:https://www.cnblogs.com/joeylee97/p/6675092.html
Copyright © 2011-2022 走看看