kmp(前中后最长相同长度)

http://acm.hdu.edu.cn/showproblem.php?pid=4763

Theme Section

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5815    Accepted Submission(s): 2890

Problem Description

It‘s
time for music! A lot of popular musicians are invited to join us in
the music festival. Each of them will play one of their representative
songs. To make the programs more interesting and challenging, the hosts
are going to add some constraints to the rhythm of the songs, i.e., each
song is required to have a ‘theme section‘. The theme section shall be
played at the beginning, the middle, and the end of each song. More
specifically, given a theme section E, the song will be in the format of
‘EAEBE‘, where section A and section B could have arbitrary number of
notes. Note that there are 26 types of notes, denoted by lower case
letters ‘a‘ - ‘z‘.

To get well prepared for the festival, the
hosts want to know the maximum possible length of the theme section of
each song. Can you help us?

Input

The
integer N in the first line denotes the total number of songs in the
festival. Each of the following N lines consists of one string,
indicating the notes of the i-th (1 <= i <= N) song. The length of
the string will not exceed 10^6.

Output

There
will be N lines in the output, where the i-th line denotes the maximum
possible length of the theme section of the i-th song.

Sample Input

5
xy
abc
aaa
aaaaba
aaxoaaaaa

Sample Output

0
0
1
1
2

Source

2013 ACM/ICPC Asia Regional Changchun Online

Recommend

liuyiding

题意:求前中后最长相同串长度,不能有重叠,

我还以为我这种方法会超时,没想到过了。!!

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include <stdio.h>
#include <string.h>
#define INF  10000000
using namespace std;
char a[1000009] , b[1000009], str[200009];
int ans = 0 ;

void getnext(char *a , int len , int *next)
{
    next[0] = -1 ;
    int k = -1 , j = 0 ;
    while(j < len)
    {
        if(k == -1 || a[j] == a[k])
        {
            k++;
            j++;
            next[j] = k ;
        }
        else
        {
            k = next[k];
        }
    }
}

int main()
{
    int n ;
    scanf("%d" , &n);
    while(n--)
    {
        int next[1000009];
        int next1[1000009];
        scanf("%s" , a);
        int len = strlen(a);
        getnext(a , len , next);
        int q = next[len];
        while(q > 0)
        {
            if(q * 3 > len)
            {
                q = next[q];
                continue ;
            }
            for(int i = 0 ; i < q ; i++)
            {
                str[i] = a[i] ;
            }
            getnext(a , q , next1);
            int j = 0 , i = q ;
            while(i < len - q && j < q)
            {
                if(j == -1 || str[j] == a[i])
                {
                    i++;
                    j++;
                }
                else
                {
                    j = next[j] ;
                }
            }
            if(j == q)
            {
                ans = q;
                break ;
            }
            q = next[q];

        }
        printf("%d\n" , q);
    }

    return 0 ;
}

原文地址:https://www.cnblogs.com/nonames/p/11296313.html

时间: 2024-10-28 16:22:06

kmp(前中后最长相同长度)的相关文章

二叉树的建立及其前中后序遍历

1 //二叉树存储结构: 2 struct node 3 { 4 Int data; 5 node *lchild; 6 node *rchild; 7 }; 8 9 //二叉树在建树前根节点不存在: 10 Node *root = NULL; 11 12 //新建结点: 13 node *newNode(int v) 14 { 15 node *Node = new node; 16 Node->data = v; 17 Node->lchild = NULL; 18 Node->rc

前中后序建立树或者直接历遍

前中后序建立树或者直接历遍 代码实现 void postOrder(int root,int start,int end) { if (start > end) return; int index = start; while (inOrder[index] != preOrder[root] ) index++; postOrder(root + 1, start, index - 1); postOrder(root + index - start + 1, index + 1, end);

二叉树的前中后序遍历简单的递归

二叉树的遍历 无外乎广度和深度 其中深度又分为前中后序遍历三种情况  这三种遍历若只是递归方法 自然很是简单 但递归代码简单 若嵌套层次太深 会栈溢出 二叉树节点数据结构: struct Binary_node{    int val;    Binary_node *left;    Binary_node *right;    Binary_node(int v = 0, Binary_node *le = nullptr, Binary_node *ri = nullptr) :val(v

非递归前中后序遍历二叉树

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 写在前面: 最近准备找工作,捡起原来学习过的各种知识,加上一些自己的理解,梳理一下流程,巩固自己的认识,一步两步,一步两步... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 二叉树的遍历是树操作的基础,一般的前中后序递归遍历比较简单,这里就不列出了,主要是非递归实

二叉树的前序建立,前中后序遍历的非递归算法

二叉树的前序建立递归算法以及前中后序遍历的递归算法已经是人尽皆知了,递归算法也确实为代码的编写带来了很大的方便.然而,有时我们也确实需要它们的非递归算法.将递归算法转化为非递归算法可以帮助我们深入了解函数的调用与栈的原理.这里总结一下二叉树的这些重要的非递归算法. 一.前序建树 前序建树的基本思路是,接收用户输入的一组字符串,其中'#'代表空树,其他代表树结点的数据域值.例如,要建立如下一棵树 需要输入"AB#D##C##". 而非递归的思路是,1.设一个标志位来判断当前创建的结点是左

Qt实现 动态化遍历二叉树(前中后层次遍历)

binarytree.h 头文件 1 #ifndef LINKEDBINARYTREE_H 2 #define LINKEDBINARYTREE_H 3 #include<c++/algorithm> 4 #include<c++/cstdio> 5 #include<string> 6 #include<c++/string> 7 #include<c++/vector> 8 #include<vector> 9 #include&

关于前中后序排列

大致可以总结如下: 前序排列(preorder):根左右 中序排列(inorder):左根右 后续排序(postorder):左右根 重点看"根"的位置,在最前面就是前序,中间就是中序,后面就是后序.补充一点,上述排列都是DFT(深度优先排列,Depth First Traversals).另有Breadth First or Level Order Traversal . 详解 首先上个例子: 中序是左根右,所以从最左的左节点4开始(其他的还不够"左",例如2,其

【算法导论】二叉树的前中后序非递归遍历实现

二叉树的递归遍历实现起来比较简单,而且代码简洁:而非递归遍历则不那么简单,我们需要利用另一种数据结构---栈来实现.二叉树的遍历又可以分为前序.中序和后序三种,它们是按照根结点在遍历时的位置划分的,前序遍历则根结点先被遍历,中序则根结点在左右叶子节点之间被遍历,后序则是根结点最后被遍历.三种非递归遍历中,前序和中序都不是太复制,而后序遍历则相对较难. 一.前序遍历 我们这里前序遍历按照"根-左-右"的顺序来遍历.这里按照"递归--非递归"的次序来研究,之后的几种亦是

web前端工程师(实习生)面试前中后

金三银四是对应聘工作的要把握时间的一种描述. 面试前 我是从去年下半年才开始接触web前端知识的,刚开始学习前端知识的时候,虽说是在学院的一个工作室进行学习的,但是因为交流少等原因,导致自己一开始走了一些弯路.感觉直到今年的开学之际,意识到自己要找实习了,翻看网上的一些面经等,才发现自己知道的实在太少了,甚至可以说对前端一无所知.这么说吧,虽然我也看了<javascript高级程序设计>,<锋利的jquery>,<javascript Dom编程艺术>等,但是学了几个月