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);
        }
    }
  • 相关阅读:
    全面了解Nginx主要应用场景
    手把手教你构建 C 语言编译器
    Docker镜像原理和最佳实践
    Docker网络深度解读
    PostgreSQL 10.0 preview 功能增强
    阿里沈询:分布式事务原理与实践
    CPU、内存、IO虚拟化关键技术及其优化探索
    原理、方法双管齐下,大神带你细解Redis内存管理和优化---场景研读
    ASP.NET 5已终结,迎来ASP.NET Core 1.0和.NET Core 1.0 转
    RabbitMQ学习系列
  • 原文地址:https://www.cnblogs.com/joeylee97/p/6675092.html
Copyright © 2011-2022 走看看