• 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("");
        }
    }
    
    
  • 相关阅读:
    jmeter 工具学习 未完待续
    测试学习
    JavaScript
    新概念第1册
    day08
    LeetCode OJ:Invert Binary Tree(反转二叉树)
    LeetCode OJ:Lowest Common Ancestor of a Binary Search Tree(最浅的公共祖先)
    LeetCode OJ:Maximum Depth of Binary Tree(二叉树最大深度)
    LeetCode OJ:Path Sum(路径之和)
    LeetCode OJ:Symmetric Tree(对称的树)
  • 原文地址:https://www.cnblogs.com/thmyl/p/8092591.html
Copyright © 2020-2023  润新知