zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言I博客作业02
    C语言II博客作业04
    C语言II博客作业03
    C语言II博客作业02
    C语言II博客作业01
    学期总结
    C语言I博客作业08
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3346346.html
Copyright © 2011-2022 走看看