1. 程式人生 > >HDU 1358 Period 求前綴長度和出現次數(KMP的next數組的使用)

HDU 1358 Period 求前綴長度和出現次數(KMP的next數組的使用)

整除 ever mem ges some ble div 使用 周期性

Period

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12428 Accepted Submission(s): 5825


Problem Description 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.

Input The input file consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S. The second line contains the string S. The input file ends with a line, having the number zero on it.

Output For each test case, output “Test case #” and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.

Sample Input 3 aaa 12 aabaabaabaab 0

Sample Output Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4

Recommend JGShining | We have carefully selected several similar problems for you: 1686 3336 3746 3068 2203 題目大意:
給一個字符串,從第二個字符開始,讓你判斷前面字符串是否具有周期性,然後輸出此位置和最大周期數。(周期要大於一) 思路: 先構造出 next[] 數組,下標為 i,定義一個變量 j = i - next[i] 就是next數組下標和下標對應值的差,如果這個差能整除下標 i,即 i%j==0 ,則說明下標i之前的字符串(周期性字符串長度為 i)一定可以由一個前綴周期性的表示出來,這個前綴的長度為剛才求得的那個差,即 j,則這個前綴出現的次數為 i/j 。所以最後輸出i和i/j即可。 code:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<memory>
using namespace std;
char wenben[1000005];
int next1[1000005];
void getnext1(char* s,int* next1,int m)
{
    next1[0]=0;
    next1[1]=0;
    for(int i=1;i<m;i++)
    {
        int j=next1[i];
        while(j&&s[i]!=s[j])
            j=next1[j];
        if(s[i]==s[j])
            next1[i+1]=j+1;
        else
            next1[i+1]=0;
    }
}
int main()
{
    int L;
    int t=1;
    while(~scanf("%d",&L))
    {
        if(L==0)
            break;
        scanf("%s",wenben);
        getnext1(wenben,next1,L);
        for(int i=0;i<L;i++)
            printf("i=%d->%d ",i,next1[i]);
        printf("\n");
        printf("Test case #%d\n",t++);
        for(int i=2;i<=L;i++)
        {
            int k=i-(next1[i]);
            if(k!=i&&(i)%k==0)
                printf("%d %d\n",i,i/k);
        }
        printf("\n");
    }
    return 0;
}

HDU 1358 Period 求前綴長度和出現次數(KMP的next數組的使用)