最小循环节

 

输入

The input consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S.The second line contains the string S. The input file ends with a line, having the 
number zero on it.

输出

For each test case, output "Test case #" and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.

 

样例输入

3
aaa
12
aabaabaabaab
0

样例输出

Test case #1
2 2
3 3

Test case #2
2 2
6 2
9 3
12 4

     本题是最小循环节问题,就是利用kmp的next数组的一种问题。

             循环节的次数一定等于    len/(len-next[i])      


 

思路: KMP 
#include<iostream>

#include<string.h>

using namespace std;

char a[1000000];

int next1[1000000];

void getnext(int len)

{

    int i = 0, j = -1;

    next1[0] = -1;

    while(i != len)  //或者换成for(i=0;i<n;) 注意for循环中的i应该从0开始计数,因为下面有i++也就是说得到的第一个是next1[1];

    {                                                       //next[]的特点是:初值-1,整体右移一位。

        if(j == -1 || a[i] == a[j])

            next1[++i] = ++j;                          //next[]数组里的放的是i之前(不包括i)的最长前后缀长                                                                           度,且长度是从1开始的。

        else

            j = next1[j];

    }

}

int main()

{

    int n,i,lena,t=0;

    while(cin>>n&&n)

    {

        cin>>a;

        cout<<"Test case #"<<++t<<endl;

        getnext(n);           //这个地方再次写这道题时没注意到,不要用strlen(a)来代替字符串长度,由于输入比较                                                                      大,所以如果用会超时的。

          for(int i = 1; i <= n; ++i)   //不要用strlen(a)来代替字符串长度,用n。题目给n的目的就在这呢。

        {

            lena = i - next1[i];

            if(i != lena && i % lena == 0)

                cout<<i<<" "<<i/lena<<endl;

        }

        cout<<endl;

    }

    return 0;

}

    2018-7-1           快要考数据结构实验了,我现在慌的一批。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值