Period [HDU 1358]

时间:2021-08-05
本文章向大家介绍Period [HDU 1358],主要包括Period [HDU 1358]使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目:

For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as AK , that is A concatenated K times, for some string A. Of course, we also want to know the period K.

分析:

该题求每个长度大于等于2的前缀连续出现的最大次数(从前缀的位置开始)。

我的next[i]表示和以这一位结尾的后缀相同的前缀的末尾的位置,如

a a b a a c
0 1 0 1 2 0

a a b a a b a a b a a b
0 1 0 1 2 3 4 5 6 7 8 9

我们发现这样一个规律:所有满足题目条件的,都满足 (i%(i-nxt[i])==0.

code

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int lena, lenb, nxt[1000005];
char a[1000005], b[1000005];
void mknxt(){
	int j=0, k;
	k = nxt[0] = -1;
	while(j<lenb){
		if(k==-1 || b[j]==b[k])	nxt[++j] = ++k;
		else	k = nxt[k];
	}
} 
int main(){
    while(1){
	cin>>lenb;
    if(!lenb)break;
    scanf("%s", b); 
	mknxt(); 
    printf("Test case #%d\n",++lena);
	for(int i=2; i<=lenb; i++)	{
        if(nxt[i]){
            if(i%(i-nxt[i])==0){
                printf("%d %d\n",i,i/(i-nxt[i]));
            }
        }
    }
    printf("\n");
    
    }
	return 0;
}


原文地址:https://www.cnblogs.com/GUOGaby/p/15102751.html