CF 432D

http://codeforces.com/problemset/problem/432/D

在前缀是后缀的前提下,求这个前缀在原串中出现了多少次

出现的次数可以用dp求解,前缀是后缀直接用Next判断,较为综合的kmp考察,这题没写出来就是kmp基础不牢,不应该

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std ;

char B[100005] ;

int Next[100005],lenA,lenB,dp[100005] ;

void GetNext()

{

    int i,j ;

    Next[1]=0 ;  

    j=0 ;

    for(i=2 ;i<=lenB ;i++)

    {

        while(j>0 && (B[j+1]!=B[i]))j=Next[j] ;

        if(B[j+1]==B[i])j++ ;

        Next[i]=j ;

    }

}

struct node

{

    int p,q ;

}ans[100005] ;

int cmp(node c,node d)

{

    return c.p<d.p ;

}

int main()

{

    scanf("%s",B+1) ;

    lenB=strlen(B+1) ;

    GetNext() ;

    for(int i=0 ;i<=lenB ;i++)

        dp[i]=1 ;

    for(int i=lenB ;i>0 ;i--)

    { 

        dp[Next[i]]+=dp[i] ;//前缀在原串中出现了多少次 

        /*

        int j=Next[i] ;

        while(1)

        {

            if(!j)break ;

            dp[j]++ ;

            j=Next[j] ;

        }

        */

    }

    int st=0 ;

    for(int i=lenB ;i>0 ;i=Next[i])//判断前缀是后缀 

        ans[st].p=i,ans[st++].q=dp[i] ;

    sort(ans,ans+st,cmp) ;

    printf("%d\n",st) ;

    for(int i=0 ;i<st ;i++)

        printf("%d %d\n",ans[i].p,ans[i].q) ;

    return 0 ;

}
View Code

 

你可能感兴趣的:(c)