循环节(SDUT 2747)

来源:互联网 发布:开源平台系统源码 编辑:程序博客网 时间:2024/05/04 17:12

循环节

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

X最近爱上了一种奇怪的游戏,就是找出一个字符串中的最小循环节。
对于最小循环节的定义:对于字符串A存在字串B,使得A是由N个完整的B组成的,那么B就是A的一个循环节,长度最小的那一个为最小循环节。

输入

多组输入。
每组输入一个字符串,长度不大于80,只包含26个小写字母。

输出

输出一个字符串,代表最小循环节。

示例输入

aaaaabab

示例输出

aab

提示

 

来源

 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;}



0 0
原创粉丝点击