POJ-2406-Power Strings

这题的话是next数组的性质来做的,假设next[len],它表示的意思就是对于len之前,总共有几个重复的。

既然是重复的,那就可以把前面重复的删掉,然后后面的就是完全不重复的一节,然后它就是最短循环节。

具体图示在这篇博客里面:https://www.cnblogs.com/xyqxyq/p/10397187.html

我们知道,如果next[len]此时为0,说明之前没有任何重复,所以它的循环次数就是1,要么我们就输出

len/(len-next[len]).

这个思路的问题在哪?假设我们有abcdab,这时候,我们知道next[len]不为0,然后我们就认为它是循环的,

然后我们就用公式输出了一个错误的答案。

正确的思路是,我们可以先用公式判断,即len%(len-next[len])==0,如果为真,说明有循环节,否则我们就输出1。

#include <cstdio>
#include <cstring>
const int maxn=1000005;
char s[maxn];
int next[maxn]; 

void getnext()
{
    next[0]=-1;
    int j=0,k=-1;
    int len=strlen(s);
    while (j<=len) {
        if (k==-1||s[j]==s[k])
            next[++j]=++k;
        else 
            k=next[k];
    }
}

int main()
{
    while (scanf("%s",s)&&s[0]!='.') {
        getnext();
        int len=strlen(s);
        if (len%(len-next[len])==0)
            printf("%d\n",len/(len-next[len]));
        else
            printf("1\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xyqxyq/p/10404637.html
今日推荐