AcWing 141 周期

题目:https://www.acwing.com/problem/content/143/

一个字符串的前缀是从第一个字符开始的连续若干个字符,例如”abaab”共有5个前缀,分别是a, ab, aba, abaa, abaab。

我们希望知道一个N位字符串S的前缀是否具有循环节。

换言之,对于每一个从头开始的长度为 i (i>1)的前缀,是否由重复出现的子串A组成,即 AAA…A (A重复出现K次,K>1)。

如果存在,请找出最短的循环节对应的K值(也就是这个前缀串的所有可能重复节中,最大的K值)。

输入格式

输入包括多组测试数据,每组测试数据包括两行。

第一行输入字符串S的长度N。

第二行输入字符串S。

输入数据以只包括一个0的行作为结尾。

输出格式

对于每组测试数据,第一行输出 “Test case #” 和测试数据的编号。

接下来的每一行,输出具有循环节的前缀的长度i和其对应K,中间用一个空格隔开。

前缀长度需要升序排列。

在每组测试数据的最后输出一个空行。

数据范围

2N10000002≤N≤1000000

输入样例:

3
aaa
4
abcd
12
aabaabaabaab
0

输出样例:

Test case #1
2 2
3 3

Test case #2

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

题意:
没啥好的,简单的next数组求循环节长度,很水。向我最开始学kmp的时候用的是 len-next[len],以为只有总长度才能用这个公式。
根据题意从1到n遍历next数组, i-next[i]求的是当前状态的循环节长度,当i%(i-next[i])==0的时候说明这一段完全由该循环节组成,个数是 i/(i-next[i])。
代码:
 1 #include <map>
 2 #include <stack>
 3 #include <queue>
 4 #include <cmath>
 5 #include <string>
 6 #include <limits>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <cstdlib>
10 #include <cstring>
11 #include <iostream>
12 #include <algorithm>
13 #define Scc(c) scanf("%c",&c)
14 #define Scs(s) scanf("%s",s)
15 #define Sci(x) scanf("%d",&x)
16 #define Sci2(x, y) scanf("%d%d",&x,&y)
17 #define Sci3(x, y, z) scanf("%d%d%d",&x,&y,&z)
18 #define Scl(x) scanf("%I64d",&x)
19 #define Scl2(x, y) scanf("%I64d%I64d",&x,&y)
20 #define Scl3(x, y, z) scanf("%I64d%I64d%I64d",&x,&y,&z)
21 #define Pri(x) printf("%d
",x)
22 #define Prl(x) printf("%I64d
",x)
23 #define Prc(c) printf("%c
",c)
24 #define Prs(s) printf("%s
",s)
25 #define For(i,x,y) for(int i=x;i<y;i++)
26 #define For_(i,x,y) for(int i=x;i<=y;i++)
27 #define FFor(i,x,y) for(int i=x;i>y;i--)
28 #define FFor_(i,x,y) for(int i=x;i>=y;i--)
29 #define Mem(f, x) memset(f,x,sizeof(f))
30 #define LL long long
31 #define ULL unsigned long long
32 #define MAXSIZE 1000010
33 #define INF 0x3f3f3f3f
34 
35 #include <bits/stdc++.h>
36 const int mod=1e9+7;
37 const double PI = acos(-1.0);
38 
39 //using namespace std;
40 char s[MAXSIZE];
41 int next[MAXSIZE];
42 int n;
43 void getnext()
44 {
45     int i=0,j=-1;
46     next[0]=-1;
47     while(i<n)
48     {
49         if(j!=-1&&s[i]!=s[j])
50             j=next[j];
51             else
52         {
53             i++;
54             j++;
55             next[i]=j;
56         }
57     }
58 }
59 int main()
60 {
61     int k=1;
62     while(scanf("%d",&n)&&n)
63     {
64         scanf("%s",s);
65         printf("Test case #%d
",k++);
66         getnext();
67         for(int i=1; i<=n; i++)
68         {
69             if( i!=(i-next[i]) &&! (i%(i-next[i]) ))
70                 printf("%d %d
",i, i/(i-next[i]) );
71         }
72         Prs("");
73     }
74     return 0;
75 }
View Code
emmmmm  我把输出中的“Test”写成了“Text”,调了一下午,一直wa,愣是没发现,简直怀疑人生了。
原文地址:https://www.cnblogs.com/hbhdhd/p/11426979.html