zoukankan      html  css  js  c++  java
  • (KMP Next的运用) Period II -- fzu -- 1901

    http://acm.fzu.edu.cn/problem.php?pid=1901

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#problem/Q

    Period II
    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Description

    For each prefix with length P of a given string S,if

    S[i]=S[i+P] for i in [0..SIZE(S)-p-1],

    then the prefix is a “period” of S. We want to all the periodic prefixs.

    Input

    Input contains multiple cases.

    The first line contains an integer T representing the number of cases. Then following T cases.

    Each test case contains a string S (1 <= SIZE(S) <= 1000000),represents the title.S consists of lowercase ,uppercase letter.

    Output

    For each test case, first output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the number of periodic prefixs.Then output the lengths of the periodic prefixs in ascending order.

    Sample Input

    4
    ooo
    acmacmacmacmacma
    fzufzufzuf
    stostootssto

    Sample Output

    Case #1: 3
    1 2 3
    Case #2:
    6 3 6 9 12 15 16
    Case #3: 4
    3 6 9 10
    Case #4: 2
    9 12
     
    给你一个字符串 s 求出所有满足s[i] == s[i+p] ( 0 < i+p < len )的 p ;
     
    其实就是这个字符串的后缀与前缀的最大匹配 next[N],然后用最大匹配的串继续找匹配的前缀,比如下面的数据:
     
    aaabaaa:--> P = 4  <---> next[7] = 3
    aaabaaa:--> P = 5  <---> next[3] = 2
    aaabaaa:--> P = 6  <---> next[2] = 1
    aaabaaa:--> P = 7  <---> next[1] = 0
     
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn = 1000050;
    
    char s[maxn];
    int Next[maxn], ans[maxn];
    
    void FindNext(char s[])
    {
        int slen = strlen(s), i=0, j=-1;
        Next[0] = -1;
    
        while(i<slen)
        {
            if(j==-1 || s[i]==s[j])
                Next[++i] = ++j;
            else
                j = Next[j];
        }
    }
    
    int main()
    {
        int t, iCase=1;
        scanf("%d", &t);
        while(t--)
        {
            scanf("%s", s);
    
            int len = strlen(s);
    
            FindNext(s);
    
            int cnt = 0, k=len;
    
            while(Next[k]!=0)
            {
                ans[cnt++] = len-Next[k];  /// 第 cnt 个子串结束的下标, 表示自己觉得很神奇
                k = Next[k];
            }
    
            printf("Case #%d: %d
    ", iCase++, cnt+1);
            for(int i=0; i<cnt; i++)
                printf("%d ", ans[i]);
            printf("%d
    ", len);
        }
        return 0;
    }
     
     
     
     
    勿忘初心
  • 相关阅读:
    1008: 约瑟夫问题
    1009: 恺撒Caesar密码
    1006: 日历问题
    1007: 生理周期
    Asp.Net Core 发布和部署( MacOS + Linux + Nginx )
    ASP.NET Core Docker部署
    Asp.Net Core 发布和部署(Linux + Jexus )
    ASP.NET Core 十种方式扩展你的 Views
    基于机器学习的web异常检测
    Disruptor深入解读
  • 原文地址:https://www.cnblogs.com/YY56/p/4849546.html
Copyright © 2011-2022 走看看