Period POJ - 1961

Period

POJ - 1961

时限: 3000MS   内存: 30000KB   64位IO格式: %I64d & %I64u

提交 状态

已开启划词翻译

问题描述

For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as A K ,that is A concatenated K times, for some string A. Of course, we also want to know the period K.

输入

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

来源

Southeastern Europe 2004

题意:一个字符串的前缀,可以由其最小的循环节循环k(k>1, 次得到。按升序输出这样的前缀的长度。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4
 5 using namespace std;
 6
 7 #define maxn 1000008
 8
 9 char s[maxn];
10 int next[maxn];
11
12 void getNext()
13 {
14     int j, k, i;
15     i = strlen(s);
16
17     j = 0;
18     k = -1;
19     next[0] = -1;
20     while(j < i)
21     {
22         if(k == -1 || s[j] == s[k])
23         {
24             j++;
25             k++;
26             next[j] = k;
27         }
28         else
29             k = next[k];
30     }
31 }
32
33 int main()
34 {
35     int q, p = 1;
36     while(scanf("%d", &q), q)
37     {
38         scanf("%s", s);
39
40         memset(next, 0, sizeof(next));
41         getNext();
42
43         printf("Test case #%d\n", p++);
44
45         for(int i = 2; i <= q; i++)
46         {
47             int k = next[i]; // 这个前缀的,前缀和后缀最长的相等长度
48             if(i % (i - k) == 0 && i / (i - k) != 1)  // 满足循环节……循环 输出
49                 printf("%d %d\n", i, i / (i - k));
50         }
51         puts("");
52     }
53     return 0;
54 }
时间: 2024-11-15 07:27:40

Period POJ - 1961的相关文章

POJ 1961 Period

Period Time Limit: 3000ms Memory Limit: 30000KB This problem will be judged on PKU. Original ID: 196164-bit integer IO format: %lld      Java class name: Main For each prefix of a given string S with N characters (each character has an ASCII code bet

poj 1961 Period 【KMP-next前缀数组的应用】

题目地址:http://poj.org/problem?id=1961 Sample Input 3 aaa 12 aabaabaabaab 0 Sample Output Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4 题目分析:给你一个字符串,最大长度1百万.输出是:以第1组样例解释,在aaa的字符串中,长度为2时,存在2个循环节a.当长度为3时,存在3个循环节a.以第二组样例解释,当长度为2时,存在2个循环节a.当长度为6时,存在2个循

(简单) POJ 1961 Period,扩展KMP。

Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the larges

poj 1961 Period【求前缀的长度,以及其中最小循环节的循环次数】

Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 14653   Accepted: 6965 Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the

poj 1961 Period(KMP求周期)

Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 15963   Accepted: 7644 Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the

Period (poj 1961&amp;&amp;hdu 1358)KMP

Language: Default Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 13504   Accepted: 6365 Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want t

Period(poj 1961)

题目大意: 给你一个字符串,求这个字符串到第i个字符为止的循环节的次数. 比如aabaabaabaab,长度为12.到第二个a时,a出现2次,输出2.到第二个b时,aab出现了2次,输出2.到第三个b时,aab出现3次,输出3.到第四个b时,aab出现4次,输出4. KMP!!! #include<cstdio> #include<iostream> #include<cstring> #define M 1000010 using namespace std; int

POJ 1961 Period (KMP)

解题思路: 利用next 数组的性质求解重复子串.循环节的长度为i - next[i]; #include <iostream> #include <cstring> #include <cstdlib> #include <vector> #include <cmath> #include <algorithm> #include <cstdio> using namespace std; const int maxn

【poj 1961】Period(字符串--KMP循环节)

题意:给你一个字符串,求这个字符串到第 i 个字符为止的重复子串的个数. 解法:判断重复子串的语句很重要!!if (p && i%(i-p)==0) printf("%d %d\n",i,i/(i-p)); 我之前一直不是很理解,而实际上多枚举几种情况就好了.若是重复的,那么next[i]肯定是最大值,值余下一个循环节不同:而若不是,next[i]表示的前缀和后缀串的和重叠部分不一样以外的部分就肯定空出来,不能整除的.(P.S.我在说些什么......m(._.)m)