POJ-1961 Period
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ-1961 Period相关的知识,希望对你有一定的参考价值。
Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 16641 | Accepted: 8003 |
Description
Input
number zero on it.
Output
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
题目大意:
给你一个字符串,求这个字符串到第i个字符为止的循环节的次数。
比如aabaabaabaab,长度为12。到第二个a时,a出现2次,输出2.到第二个b时,aab出现了2次,输出2.到第三个b时,aab出现3次,输出3.到第四个b时,aab出现4次,输出4。
【输入】
输入包含多组测试数据。
每个测试数据由两行组成。 第一行一个N(2 < = N < = 1 000 000)表示字符串的长度。 第二行包含该字符串。
输入文件最后一行,有一个0 表示结束。
【输出】
每组结果先输出“Test case #“,及表示第几组的整数。
之后每行输出两个正整数表示 到长度为多少时,重复次数为多少。(重复次数为0的不输出)
解题思路:
这道题好像就是POJ 2406的加强版而已。那道题是输出一个字符串的循环节出现的次数,这个是到第i个字符为止,其实就是多了一层循环。把这个字符串遍历一次即可。。做完那道题就顺便把这道题给A了。
附poj2406题解
思路:KMP,next表示模式串如果第i位(设str[0]为第0位)与文本串第j位不匹配则要回到第next[i]位继续与文本串第j位匹配。则模式串第1位到next[n]与模式串第n-next[n]位到n位是匹配的。所以思路和上面一样,如果n%(n-next[n])==0,则存在重复连续子串,长度为n-next[n]。
例如: a b a b a b
next:-1 0 0 1 2 3 4
next[n]==4,代表着,前缀abab与后缀abab相等的最长长度,这说明,ab这两个字母为一个循环节,长度=n-next[n];
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn=1000005; 8 int Next[maxn]; 9 char str[maxn]; 10 int N; 11 12 void get_next() 13 { 14 int j,k; 15 Next[0]=-1; 16 j=0;k=-1; 17 while(j<N) 18 { 19 if(k==-1||str[k]==str[j]) 20 { 21 k++;j++; 22 Next[j]=k; 23 } 24 else 25 k=Next[k]; 26 } 27 } 28 29 int main() 30 { 31 int t(0),k; 32 while(scanf("%d\\n",&N)!=EOF) 33 { 34 if(N==0) break; 35 t++; 36 printf("Test case #%d\\n",t); 37 gets(str); 38 memset(Next,0,sizeof(Next)); 39 get_next(); 40 k=0; 41 for(int i=2;i<=N;i++) 42 if(Next[i]!=0&&Next[i]!=i&&i%(i-Next[i])==0) printf("%d %d\\n",i,i/(i-Next[i])); 43 printf("\\n"); 44 } 45 return 0; 46 }
以上是关于POJ-1961 Period的主要内容,如果未能解决你的问题,请参考以下文章