HDU 1358 Period(KMP求前缀子串的循环次数)
2015-08-19 20:43
471 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358
题目大意:给定一个字符串s,然后对于所有的前缀子串,如果是一个周期循环的子串,那么就输出他的长度和循环了几次。
解:如果长度为k的串是以t为周期循环的,那么之后存在一个i满足next[i] * 2 > l,即超过一半的长度且next[i] = k。那么可以知道i串的循环周期是和n长度为k的串一致。 举例说明如下:看不懂上面那句话的,直接看下面的例子吧。
i 0 1 2 3 4 5 6 7 8 9
char a b c a b c a b c
next 0 0 0 0 1 2 3 1 5 6
然后当i= 6时,有next[i] * 2 = i,表明前面的一个串循环了两次,且周期week[i] = next[i] = 3,
当 i=8时,有 next[i] * 2 > i,next[i] = 5;但是week[5] = 0,就是长度为5的串没有周期。所以i=8也没有周期
i=9, 有next[i] * 2> i, next[i] = 6; week[6]的周期为3,所以week[i]=3.
这个可以这样看,i=6时,有abcabc。i=9时是abcabcxxx,因为abcabc = abcxxx(由next数组可知),那么xxx就一定是abc,也就是一个周期。
那么最后只要周期长度大于0的输出就可以了,具体重复了几次周期就是i / week[i]。
网上的方法没有用到数组,当然自己做的时候没想太多哈。
题目大意:给定一个字符串s,然后对于所有的前缀子串,如果是一个周期循环的子串,那么就输出他的长度和循环了几次。
解:如果长度为k的串是以t为周期循环的,那么之后存在一个i满足next[i] * 2 > l,即超过一半的长度且next[i] = k。那么可以知道i串的循环周期是和n长度为k的串一致。 举例说明如下:看不懂上面那句话的,直接看下面的例子吧。
i 0 1 2 3 4 5 6 7 8 9
char a b c a b c a b c
next 0 0 0 0 1 2 3 1 5 6
然后当i= 6时,有next[i] * 2 = i,表明前面的一个串循环了两次,且周期week[i] = next[i] = 3,
当 i=8时,有 next[i] * 2 > i,next[i] = 5;但是week[5] = 0,就是长度为5的串没有周期。所以i=8也没有周期
i=9, 有next[i] * 2> i, next[i] = 6; week[6]的周期为3,所以week[i]=3.
这个可以这样看,i=6时,有abcabc。i=9时是abcabcxxx,因为abcabc = abcxxx(由next数组可知),那么xxx就一定是abc,也就是一个周期。
那么最后只要周期长度大于0的输出就可以了,具体重复了几次周期就是i / week[i]。
网上的方法没有用到数组,当然自己做的时候没想太多哈。
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<algorithm> using namespace std; char a[1000005]; int Next[1000005]; int week[1000005]; void getNext(int len) { int i = 0, j = -1; Next[0] = -1; while(i < len) { if(j == -1 || a[i] == a[j]) { Next[++i] = ++j; } else { j = Next[j]; } } } int main () { int n, cas = 1; while (scanf("%d", &n), n) { scanf("%s", a); memset(week, 0, sizeof(week)); printf("Test case #%d\n", cas++); getNext(n); for (int i = 2; i <= n; i ++) { if(Next[i] * 2 == i) { week[i] = Next[i]; } if(Next[i] * 2 > i) { week[i] = week[Next[i]]; } if(week[i] > 0) { printf("%d %d\n", i, i / week[i]); } } printf("\n"); } return 0; }
相关文章推荐
- Poj 2516 Minimum Cost (最小花费最大流)
- PHP与JAVA通信
- 常见的Web负载均衡方法
- 动态内存开辟函数
- 入门视频采集与处理(BT656简介) 转
- 《AndroidStudio每日一贴》2.快速查看项目中最近的变更
- 低头做人,抬头做事
- 个人--IT职业规划表
- Java异常体系
- Java相关知识(一)
- poj 1442 Black Box
- 求两个分数的加减乘除,并比较大小
- 142. Linked List Cycle II
- [转]Spring MVC之@RequestMapping 详解
- 【进阶——种类并查集】hdu 1829 A Bug's Life (基础种类并查集)TUD Programming Contest 2005, Darmstadt, Germany
- 文件及文本管理命令 cp,cut,sort,uniq,tr详解
- web前端选项卡demo
- Hbuilder开发app实战-识岁02-拍照和选取照片
- poj 2135 Farm Tour 最小费最大流
- laravel 登录验证