FZU 1901 最小循环节

Problem 1901 Period II

Accept: 676    Submit: 1825
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

For each prefix with length P of a given string S,if

S[i]=S[i+P] for i in [0..SIZE(S)-p-1],

then the prefix is a “period” of S. We want to all the periodic prefixs.

 Input

Input contains multiple cases.

The first line contains an integer T representing the number of cases. Then following T cases.

Each test case contains a string S (1 <= SIZE(S) <= 1000000),represents the title.S consists of lowercase ,uppercase letter.

 Output

For each test case, first output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the number of periodic prefixs.Then output the lengths of the periodic prefixs in ascending order.

 Sample Input

4oooacmacmacmacmacmafzufzufzufstostootssto

 Sample Output

Case #1: 31 2 3Case #2: 63 6 9 12 15 16Case #3: 43 6 9 10Case #4: 29 12

 Source

FOJ有奖月赛-2010年05月

找最小循环节周期统计答案便可

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 1000024;
int ans[MAX_N];
int Next[MAX_N];
char mo[MAX_N];
int n2;
void getnext(){
int i = 0,j=-1;
while(i<n2){
    if(j==-1||mo[i]==mo[j]) {++i,++j,Next[i]=j;}
    else j = Next[j];
 }
  return ;
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int cnt = 0;
        scanf("%s",mo);
        n2 = strlen(mo);
        Next[0] = -1;
        getnext();
        int tmp = n2-Next[n2];
        for(int i=1;;i++){
            if(tmp*i>=n2) break;
            ans[cnt++] = tmp*i;
        }
        ans[cnt++] = n2;
        printf("Case #%d: %d\n",i,cnt);
     for(int k=0;k<cnt;++k){
        k==cnt-1?printf("%d\n",ans[k]):printf("%d ",ans[k]);
     }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/heucodesong/article/details/81005162
今日推荐