循环节
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
X最近爱上了一种奇怪的游戏,就是找出一个字符串中的最小循环节。
对于最小循环节的定义:对于字符串A存在字串B,使得A是由N个完整的B组成的,那么B就是A的一个循环节,长度最小的那一个为最小循环节。
输入
多组输入。
每组输入一个字符串,长度不大于80,只包含26个小写字母。
输出
输出一个字符串,代表最小循环节。
示例输入
aaaa abab
示例输出
a ab
提示
来源
zmx
示例程序
方法一
白皮书上的优化算法~orz。
<pre class="html" name="code">#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
int len,i,j,k;
int flag=0;
while(~scanf("%s",str))
{
len = strlen(str);
for(i=1; i<=len; i++)
if(len%i==0)
{
flag = 1;
for(j=i;j<len;j++)
{
if( str[j]!=str[j%i] )
{
flag = 0;
break;
}
}
if(flag)
{
for(k=0; k<i; k++)
{
printf("%c", str[k] );
}
printf("\n");
break;
}
}
}
return 0;
}
方法二
KMP
这里膜拜一下YanBaoC 这是他的代码 拿来一用
<pre class="html" name="code">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int getnext(char *s)
{
int next[81];
int i=0,j=next[0]=-1;
int l=strlen(s);
while(i<l){
if(j==-1||s[i]==s[j]){
i++;
j++;
if(s[i]==s[j])
next[i]=next[j];
else
next[i]=j;
}
else
j=next[j];
}
if(l%(l-next[l])==0)
return l/(l/(l-next[l]));
else
return l/1;
}
int main(void)
{
char s[81];
int i,j;
while(scanf("%s",s)==1){
j=getnext(s);
for(i=0;i<j;i++)
printf("%c",s[i]);
printf("\n");
}
return 0;
}