KMP与循环节相关题目

HDU 3746 Cyclic Nacklace ( KMP求最小循环节 )

len - nextval[len]即为最小循环节长度。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

const int MAXN = 100100;
const int INF  = 1 << 20;

char str[MAXN];
int nextval[MAXN];
int len;

void getNext( char s[], int next[] )
{
    int length=len;
    int i=0,j=-1;
    next[0]=-1;
    while(i<length)
    {
        if(j==-1||s[i]==s[j])
        {
            ++i;
            ++j;
            next[i]=j;
        }
        else
            j=next[j];
    }
}

int main()
{
    int T;
    scanf( "%d", &T );
    while ( T-- )
    {
        scanf( "%s", str );
        len = strlen(str);
        getNext( str, nextval );
        int sub = len - nextval[len];
        if ( sub != len && len % sub == 0 ) puts("0");
        else printf( "%d
", sub - ( nextval[len]%sub ) );
    }
    return 0;
}

 HDU 1358 Period

题意:若某串的前i个字符是循环串,输出i以及循环节出现的次数。

做法跟上一题差不多

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

const int MAXN = 1000010;

char str[MAXN];
int nextval[MAXN];
int len;

void getNext( char s[], int next[] )
{
    int length=len;
    int i=0,j=-1;
    next[0]=-1;
    while(i<length)
    {
        if(j==-1||s[i]==s[j])
        {
            ++i;
            ++j;
            next[i]=j;
        }
        else
            j=next[j];
    }
}

int main()
{
    int cas = 0;
    while ( scanf( "%d", &len ), len )
    {
        scanf( "%s", str );
        getNext( str, nextval );
        printf( "Test case #%d
", ++cas );
        for ( int i = 1; i <= len; ++i )
        {
            int sub = i - nextval[i];
            if ( i / sub > 1 && i % sub == 0 )
            {
                printf("%d %d
", i, i / sub );
            }
        }
        puts("");
    }
    return 0;
}

 POJ 2406 Power Strings(求循环串的最大循环周期)

注意这组数据:aabaabaa

显然答案是:1

#include <cstdio>
#include <cstring>
#include <cstdlib>

const int MAXN = 1000100;

char str[MAXN];
int nextval[MAXN];
int len;

void getNext(char s[],int next[])
{
    int length=len;
    int i=0,j=-1;
    next[0]=-1;
    while(i<length)
    {
        if(j==-1||s[i]==s[j])
        {
            ++i;
            ++j;
            next[i]=j;
        }
        else
            j=next[j];
    }
}

int main()
{
    while ( scanf( "%s", str ) == 1 && str[0] != '.' )
    {
        len = strlen(str);
        getNext( str, nextval );
        int sub = len - nextval[len];
        if ( len % sub == 0 ) printf("%d
", len / sub );
        else printf("1
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/GBRgbr/p/3346346.html