POJ 1961 Period || HDU 1358 Period || ZOJ 2177 Period

来源:互联网 发布:传奇盛世翅膀数据7到8 编辑:程序博客网 时间:2024/05/17 16:00
/*
给定一个长度为n的字符串s,求它的每个前缀的最短循环节。换句话说,对于每个i (2<=i<=n),
求一个最大的整数K>1 (如果K存在),使得S的前i个字符组成的前缀是某个字符串重复K次得到
的。输出所有存在K的i和对应的K。 

比如对于字符串aabaabaabaab, 只有当i=2,6,9,12时K存在,且分别为2,2,3,4 

 

用的 是很不常见的 MP 算法(其实就是个状态转移图的构造)

*/

Problem : 1358 ( Period )     Judge Status : Accepted
RunId : 7623334    Language : C++    Author : CherryChou
Code Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta
#include<functional>#include<algorithm>#include<iostream>#include<fstream>#include<sstream>#include<iomanip>#include<numeric>#include<cstring>#include<cassert>#include<cstdio>#include<string>#include<vector>#include<bitset>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<list>#include<set>#include<map>using namespace std;const int MAXN=1000015;char T[MAXN];int F[MAXN]; void getfail(char *P,int *f)// MP算法{     f[0]=f[1]=0;     int m=strlen(P);     for(int i=1;i<m;i++){       int j=f[i];       while(j&&P[i]!=P[j]) j=f[j];       f[i+1]=(P[i]==P[j]?j+1:0);     }}int main(){    int len,cnt=0;    while(~scanf("%d%*c",&len),len){      printf("Test case #%d\n",++cnt);      scanf("%s",T);      getfail(T,F);      for(int i=2;i<=len;i++){        if(F[i]>0&&i%(i-F[i])==0){          printf("%d %d\n",i,i/(i-F[i]));          }      }      puts("");    }    return 0;}

 

Source Code

Problem: 1961 User: imutzcyMemory: 5028K Time: 188MSLanguage: C++ Result: Accepted
  • Source Code
    #include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1000000 + 10;char str[maxn];int next[maxn];int n;void get_next(){int j,k;j=0;k=-1;next[0]=-1;while(str[j]!='\0'){if(k==-1||str[j]==str[k]){j++;k++;if(j%(j-k)==0&&j/(j-k)>1)  printf("%d %d\n",j,j/(j-k));next[j]=k;}else k=next[k];}}int main(){int text=0;while(~scanf("%d",&n),n){scanf("%s",str);printf("Test case #%d\n",++text);get_next();printf("\n");}return 0;}
原创粉丝点击