poj-2046-循环子串问题

来源:互联网 发布:淘宝卖家如何退出村淘 编辑:程序博客网 时间:2024/05/18 14:46

问题

题目:[poj-2046]

思路

这个题目有个结论:
若s存在循环子串,当且仅当,len可以被len - prefix[len-1]整除。连接次数为len / len-prefix[len-1].
充分性我不会证明,我就证明下必要性吧。
不放假设s = pattern * n; len = strlen(s);
显然prefix[ len - 1 ] = pattern*(n-1),这个是最长的公共前缀后缀长度。
那么,循环节的长度为len - prefix[len - 1],也就是len(pattern)。
所以,此时len可以整除len - prefix[len-1].cycle = len - prefix[len-1].

代码

#include <stdio.h>#include <string.h>#define LEN 1000000 + 10char str[LEN];int prefix[LEN];void set_prefix( int n );int main( void ){    while( scanf( "%s", str ), strcmp(str, ".") ){        int ans = 0;        int n = strlen(str);        set_prefix(n);        int cycle = n - prefix[n-1];        if( n % cycle == 0 ) ans = n/cycle;        else ans = 1;        printf( "%d\n", ans );    }    return 0;}void set_prefix( int n ){    prefix[0] = 0;    for( int i = 1; i < n; ++i ){        int k = prefix[i-1];        while( k > 0 && str[i] != str[k] ){            k = prefix[k-1];        }        if( str[i] == str[k] )            prefix[i] = k + 1;        else            prefix[i] = 0;    }}
原创粉丝点击