码迷,mamicode.com
首页 > 其他好文 > 详细

Poj 1961 Period

时间:2018-08-01 19:42:28      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:while   相同   print   period   循环   ==   复杂   scanf   getc   

题面

http://poj.org/problem?id=1961

题解

发现一个性质 一个循环的串 假设循环节长度为L 那么我们取其前size-L位,后size-L位,这两个串相同

相对应的,如果一个长度为size的串,我们取前k位,和后k位相同 那么size-k一定是这个串的循环节

所以我们只要对于每一位 找到前i位的子串的最长的前缀与对应长度的后缀相同的长度 那么i-length一定是答案

最长前缀=后缀 我们不难想到kmp的next数组

所以做一下kmp 求得next数组就做完了

复杂度$O(n)$

Code

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 using namespace std;
 5 typedef long long ll;
 6 
 7 ll read(){
 8     ll x=0,f=1;char c=getchar();
 9     while(c<0 || c>9){if(c==-)f=-1;c=getchar();}
10     while(c>=0 && c<=9){x=x*10+c-0;c=getchar();}
11     return x*f;
12 }
13 
14 int n;
15 char s[1000100];
16 int nxt[1000100];
17 
18 int main(){
19 #ifdef LZT
20     freopen("in","r",stdin);
21 #endif
22     int tc=0;
23     while(1){
24         n=read();
25         if(!n) break;
26         scanf("%s",&s);
27         nxt[0]=0,nxt[1]=0;
28         for(int i=1;i<n;i++){
29             int j=nxt[i];
30             while(j && s[i]!=s[j]) j=nxt[j];
31             nxt[i+1]=(s[i]==s[j])?j+1:0;
32         }
33         printf("Test case #%d\n",++tc);
34         for(int i=1;i<=n;i++){
35             if(i%(i-nxt[i])==0 && nxt[i]){
36                 printf("%d %d\n",i,i/(i-nxt[i]));
37             }
38         }
39         puts("");
40     }
41     return 0;
42 }

Review

动机?

kmp的一个功能就是处理循环串

这算是个模板题?

Poj 1961 Period

标签:while   相同   print   period   循环   ==   复杂   scanf   getc   

原文地址:https://www.cnblogs.com/wawawa8/p/9403392.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!