poj 2752 Seek the Name, Seek the Fame

Posted Soda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 2752 Seek the Name, Seek the Fame相关的知识,希望对你有一定的参考价值。

Seek the Name, Seek the Fame

 POJ - 2752 

题目大意:输入一串全为小写字母的字符串,字符串长度小于400000,输出所有满足前缀和后缀相等的字符的长度,这个”组合条件“我会在样例中说明。

第一组样例解释:

样例一:ababcababababcabab  2:ababcababababcabab  4:ababcabababcabab  9:ababcabab ababcabab 18: 全部

思路:

next数组的使用

下面给出描述: (i>1)[下标从0开始] 
next[i]的意义就是:前面长度为i的字串的【前缀和后缀的最大匹配长度】 

那么这题怎么利用这个性质呢? 

详细分析一下:【就用上面的第一个例子说明吧】 

a  b  a  b  c  a  b  a  b  a  b  a  b  c  a  b  a  b

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

len2 = 18    next[len2] = 9 
说明对于前面长度为18的字符串,【长度为9的前缀】和【长度为9的后缀】是匹配的, 即上图的蓝色跟红色匹配 
也就是整个串的最大前后缀匹配长度就是9了 
所以接下来根本不需要考虑长度大于9的情况啦 

好了!既然现在只需考虑长度小于9的前后缀匹配情况,那么 
[问题就转化成蓝色串的前缀跟红色串的后缀的匹配问题了!!! 
又因为蓝串==红串 
所以问题又转化成 
找蓝串自己的前缀跟自己的后缀的最大匹配了!!! 

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 400010
using namespace std;
int ans[maxn],nxt[maxn],l,cnt;
char s[maxn];
void getnxt(){
    int i=0,j=-1;
    nxt[0]=-1;
    while(i!=l){
        if(s[i]==s[j]||j==-1)nxt[++i]=++j;
        else j=nxt[j];
    }
}
int main(){
    while(scanf("%s",s)!=EOF){
        l=strlen(s);cnt=0;
        ans[++cnt]=l;
        getnxt();
        int pos=l;
        while(1){
            if(nxt[pos]==0)break;
            ans[++cnt]=nxt[pos];
            pos=nxt[pos];
        }
        for(int i=cnt;i>=1;i--)printf("%d ",ans[i]);
        puts("");
    }
}

 

 

以上是关于poj 2752 Seek the Name, Seek the Fame的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2752 Seek the Name, Seek the Fame(KMP求公共前后缀)

POJ 2752 Seek the Name, Seek the Fame

POJ2752 Seek the Name, Seek the Fame

POJ 2752 Seek the Name, Seek the Fame

poj2752 Seek the Name, Seek the Fame

poj 2752 Seek the Name, Seek the Fame