hdu1358 Period

  首先给个博客:http://blog.csdn.net/lttree/article/details/20732385

  感觉他说的很好,尤其是引用的那个博客,清晰的说明了循环节的两个公式。

  http://www.cnblogs.com/jackge/archive/2013/01/05/2846006.html

  那我就在重复一遍,这两个公式这的很重要。

对于这个循环节就是两个公式,

在i位置可以判断0~i-1的循环:

如果i%(i-next[i])==0 那么就有循环,并且next[i]!=0,

循环次数为 i/(i-next[i])

循环长度为 i-next[i]

这题还有一个坑的地方,我在代码里注释了,就是先要赋值dd,在循环,否则真的会超时,,,,坑死我了 = =

for (int i=2;i<=strlen(str);i++) 就是说这样是错的

#include <bits/stdc++.h>
using namespace std;

const int INF=0x3f3f3f3f;
typedef long long LL;
#define PI(A) printf("%d
",A)
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d%d",&(N),&(M))
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define Rep(i,a,b) for(int i=(a);i<=(b);i++)
#define reRep(i,a,b) for(int i=(a);i>=(b);i--)
//#define next Next
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */

const int MAXN= 1000000 + 5 ;

//kuangbin 模板
//Next[]调用的时候不需要初始化
int Next[MAXN];
void kmp_pre(char x[])
{
    int m=strlen(x);
    int i,j;
    j=Next[0]=-1;
    i=0;
    while(i<m)
    {
        while(-1!=j&&x[i]!=x[j]) j=Next[j];
        Next[++i]=++j;
    }
}


char str[MAXN];
int N,k;

int main()
{
    while(~SI(N),N)
    {
        scanf("%s",str);
        kmp_pre(str);
        
        //特别注意这里,一定要先把strlen(str)的值赋给dd  不能直接for (int i=2; i<=strlen(str); i++) 这样会TLE
        int dd=strlen(str);
        
        printf("Test case #%d
",++k);
        //注意注意 
        for (int i=2; i<=dd; i++)
        {
            int d=i-Next[i];
            if (i%d==0&&i>d)
            {
                printf("%d %d
",i,i/d);
            }
        }
        puts("");
    }
    return 0;
}

 第二遍,自己写的AC代码

#include <bits/stdc++.h>
using namespace std;

const int INF=0x3f3f3f3f;
typedef long long ll;
#define PU puts("");
#define PI(A) printf("%d
",A)
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d%d",&(N),&(M))
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define Rep(i,a,b) for(int i=(a);i<=(b);i++)
#define reRep(i,a,b) for(int i=(a);i>=(b);i--)
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */

const int MAXN= 1000000+9 ;
int Next[MAXN];
int len;
char x[MAXN];

void kmp_pre()
{
    int i,j;
    j=Next[0]=-1;
    i=0;
    while(i<len)
    {
        while(-1!=j&&x[i]!=x[j])j=Next[j];
        Next[++i]=++j;
    }
}
int T;
int main()
{
#ifndef ONLINE_JUDGE
    freopen("C:\Users\Zmy\Desktop\in.txt","r",stdin);
//    freopen("C:\Users\Zmy\Desktop\out.txt","w",stdout);
#endif
    while(~SI(len),len)
    {
        scanf("%s",x);
        kmp_pre();
        printf("Test case #%d
",++T);
        for (int i=2; i<=len; i++)
        {
            if (i%(i-Next[i])==0&&Next[i]!=0)
            {
                //i-Next[i]是循环串的长度,总长   除   循环串的长度就是 次数
                //                        i     /    (i-Next[i])
                printf("%d %d
",i,i/(i-Next[i]));
            }
        }
        PU;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/s1124yy/p/5671982.html