E - Period HDU-1358

题目大意:

多组。给一个n,输入长度为n 的串,求:这个串所有存在循环节的前缀,输出前缀长度和循环次数(不重叠)。

解题思路:

从i=0开始,判断前缀是不是存在循环节,即(i+1)%(i-next[i]) 是否==0 。注:next[i]值是0或-1的忽略,说明前面不存在任何循环节。(关于循环节解释的见《KMP 专题知识》)。

参考代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 using namespace std;
 4 char a[1000010];
 5 int next[1000010];
 6 int n;
 7 void GetNext()    //获得a数列的next数组
 8 {
 9     int i=0,k=-1;
10     next[0] = -1;
11     while(i<n){
12         if(k==-1){
13             next[i+1] = 0;
14             i++;k++;
15         }
16         else if(a[i]==a[k]){
17             next[i+1] = k+1;
18             i++;k++;
19         }
20         else
21             k = next[k];
22     }
23 }
24 void DisRes(int num)
25 {
26     int j;
27     printf("Test case #%d\n",num);
28     for(int i=0;i<=n;i++)
29     {
30         if(next[i]==-1 || next[i]==0)   //next[i]是-1或0的忽略,说明之前没有周期性前缀
31             continue;
32         j = i - next[i];
33         if(i%j==0)  //能整除,说明存在周期性前缀
34             printf("%d %d\n",i,i/j);    //输出这个前缀的长度和周期数
35     }
36     printf("\n");
37 }
38 int main()
39 {
40     int num = 0;
41     while(scanf("%d",&n)!=EOF)
42    {
43         if(n==0) break;
44         scanf("%s",a);
45         GetNext();  //获得next[]数组
46         DisRes(++num);  //输出结果
47     }
48     return 0;
49 }

这个回头自己写过

时间: 2024-08-28 05:50:01

E - Period HDU-1358的相关文章

Period HDU - 1358

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 (

Period - HDU 1358(next求循环节)

题目大意:有一个长N的字符串,如果前缀Ni是一个完全循环的串(循环次数大于1),输出Ni和它循环了多少次.   分析:输入next的应用,求出来next数组直接判断Ni是否是完全的循环就行了,也就是Ni % next[i] == 0下面代码 ======================================================================================================================= #include<

poj1961 &amp; hdu 1358 Period(KMP)

poj 题目链接:http://poj.org/problem?id=1961 hdu题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358 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

HDU 1358 next数组的推移

题目大意: 输入n,再输入一个长度为n的字符串,从第二位开始,计算它的前缀(包括他自己)中出现过的重复字符串的个数,如aabaabaabaab的第6位的前缀aabaab,aab连续出现了两次,所以输出位数i=6,k=2 这个题目要利用next函数求解,不断往前推移,保证往前推移的量能被i整除. 即del=i-next[i]: 保证i%del==0: 其实i%del==0成立之后不用多想了,已经可以保证前面是轮回字符串了 在此稍微进行一下理解,如next[9]=6:那么1,2,3位上的元素可以往前

KMP + 求最小循环节 --- HDU 1358 Period

Period Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=1358 Mean: 给你一个字符串,让你从第二个字符开始判断当前长度的字符串是否是重复串,如果是,输出当前位置,并输出重复串的周期. analyse: 还是next数组的运用,详见上一篇博客. Time complexity: O(N) Source code:  /** this code is made by crazyacking* Verdict: Acce

hdu 1358 Period 最小循环节

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358 分析:已知字符串,求其由最小循环节构成的前缀字符串. /*Period Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3507 Accepted Submission(s): 1766 Problem Description For ea

Hdu 1358 Period (KMP 求最小循环节)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1358 题目描述: 给出一个字符串S,输出S的前缀能表达成Ak的所有情况,每种情况输出前缀的结束位置和k. 解题思路: 打表算出next数组,然后对位置i求循环节,如果满足 i % (i - Next[i]) == 0 && Next[i] != 0,所对应的循环节(i - Next[i]), 循环次数是i / (i - Next[i]) 1 #include<cstdio> 2

HDU 1358 Period

题目链接:[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher E - Period 题意 给一字符串,求其所有完整循环的前缀与循环节的长度. 例:aaa 长度2前缀,循环节为a,个数为2 长度3前缀,循环节为a,个数为3 思路 kmp求出字符串前后缀重复数,遍历所有前缀子串进行下面操作: 字符串前后缀重复数next[L],则循环节的长度为L-L%next[L],如果L%循环节长度为0,则说明是完整循环,输出解. 代码 #include <iostream

HDU 1358 (所有前缀中的周期串) Period

题意: 给出一个字符串,在所有长度大于1的前缀中,求所有的周期至少为2的周期串,并输出一个周期的长度以及周期的次数. 分析: 有了上一题 HDU 3746 的铺垫,这道题就很容易解决了 把next求出来,然后逐个判断即可. 1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 1000000 + 10; 5 char p[maxn]; 6 int n, next[maxn]; 7 8 void get_next(

hdu 1358 period KMP入门

Period 题意:一个长为N (2 <= N <= 1 000 000) 的字符串,问前缀串长度为k(k > 1)是否是一个周期串,即k = A...A;若是则按k从小到大的顺序输出k即周期数: 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 题目其实是来自于LA的..挺好的一道题,用的是原版的kmp.. 写写对KMP