poj1961(kmp算法next数组应用)

题目链接:https://vjudge.net/problem/POJ-1961

题意:给定一个长为n的字符串(n<=1e6),对于下标i(2<=i<=n),如果子串s(1...i)是周期子串,输出其最大周期。

思路:

  考察对kmp算法中next数组的定义掌握,如果(i+1)%(i-j)==0 && (i+1)/(i-j) > 1,那么该子串即为满足条件。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int maxn=1e6+5;
int n,cas,nex[maxn];
char s[maxn];

void get_next(){
    int j;
    j=nex[0]=-1;
    for(int i=1;i<n;++i){
        while(j>-1&&s[i]!=s[j+1]) j=nex[j];
        if(s[i]==s[j+1]) ++j;
        nex[i]=j;
        if((i+1)%(i-j)==0&&(i+1)/(i-j)>1)
            printf("%d %d\n",i+1,(i+1)/(i-j));
    }
}

int main(){
    while(scanf("%d",&n),n){
        scanf("%s",s);
        printf("Test case #%d\n",++cas);
        get_next();
        printf("\n");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/FrankChen831X/p/11785429.html

时间: 2024-10-31 23:11:10

poj1961(kmp算法next数组应用)的相关文章

KMP算法&amp;next数组总结

http://www.cnblogs.com/yjiyjige/p/3263858.html KMP算法应该是每一本<数据结构>书都会讲的,算是知名度最高的算法之一了,但很可惜,我大二那年压根就没看懂过~~~ 之后也在很多地方也都经常看到讲解KMP算法的文章,看久了好像也知道是怎么一回事,但总感觉有些地方自己还是没有完全懂明白.这两天花了点时间总结一下,有点小体会,我希望可以通过我自己的语言来把这个算法的一些细节梳理清楚,也算是考验一下自己有真正理解这个算法. 什么是KMP算法: KMP是三位

POJ-2752(KMP算法+前缀数组的应用)

Seek the Name, Seek the Fame POJ-2752 本题使用的算法还是KMP 最主要的片段就是前缀数组pi的理解,这里要求解的纸盒pi[n-1]有关,但是还是需要使用一个循环来依次找到前面符合的前缀(所谓符合就是可以保持既是前缀也是s的后缀的子串长度). #include<iostream> #include<cstdio> #include<string> #include<algorithm> #include<set>

poj2406(求字符串的周期,kmp算法next数组的应用)

题目链接:https://vjudge.net/problem/POJ-2406 题意:求出给定字符串的周期,和poj1961类似. 思路:直接利用next数组的定义即可,当没有周期时,周期即为1. AC代码: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1e6+5; int n,nex[maxn],len; char s[maxn]

POJ1961 KMP算法

POJ1961 问题重述: 输入一个长度为l的字符串S,求所有S的由字串重复排列而成的前缀,并输出前缀的长度以及该前缀的最大重复度. AC代码: 1 //Memory: 5700K Time: 641MS 2 #include <iostream> 3 #include <cstring> 4 #include <string> 5 6 using namespace std; 7 8 const int maxn = 1000010; 9 10 int prefix[

A - Number Sequence HDU1005 ( kmp 算法+整数数组的应用)

A - Number Sequence Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 100000

HDU 3336 Count the string(KMP算法next数组的应用)

解题思路: 求前缀数组出现的次数之和,next[i] > 0 表示长度为next[i]的前缀又出现了一次. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <queue> #

poj2185(kmp算法next数组求最小循环节,思维)

题目链接:https://vjudge.net/problem/POJ-2185 题意:给定由大写字母组成的r×c矩阵,求最小子矩阵使得该子矩阵能组成这个大矩阵,但并不要求小矩阵刚好组成大矩阵,即边界部分可以空缺(见样例). 思路: 把每一行视作一个字符,然后对r行求next数组,那么r-nex[r]即为以行为单元的最小循环节大小ans1. 把每一列视作一个字符,然后对c列求next数组,那么c-nex[c]即为以列为单元的最小循环节大小ans2. 最终答案即ans1*ans2.(子矩阵的面积)

KMP算法——next数组求法

j 1 2 3 4 5 6 7 8 9 10 模式串 a b c a b c a c a b 部分匹配值 0 0 0 0 1 2 3 4 0 1 next[] 0 1 1 1 2 3 4 5 1 2 "部分匹配值"是"前缀"和"后缀"的最长的共有元素的长度.以"ABCDABD"为例, - "A"的前缀和后缀都为空集,共有元素的长度为0:   - "AB"的前缀为[A],后缀为[B],共有

hdoj3336(kmp算法next数组的应用)

题目链接:https://vjudge.net/problem/HDU-3336 题意:给定长为n(<=2e5)的字符串s,求s的每个前缀在s中出现的次数之和. 思路: 用dp[i]表示以s[i]为结尾的子串是s的某一种前缀的方案数,那么dp[i]=dp[nex[i]]+1,因为[nex[i]-(i-nex[i])+1 , nex[i]] 和 [nex[i]+1 , i] 是一样的,所以计算后者时只用把前者+1即可(+1是因为以[1,i]为前缀的个数加一). AC代码: #include<cs