poj2406(kmp next数组)

大意:给出一个字符串 问它最多由多少相同的字串组成

如  abababab由4个ab组成

分析:

kmp中的next数组求最小循环节的应用

例如

ababab  next[6] = 4; 即

ababab

ababab

1~4位  与2~6位是相同的

那么前两位

就等于3、4位

3、4位就等于5、6位

……

所以 如果 能整除  也就循环到最后了

如果不能整除

就最后余下的几位不在循环内

例如

1212121

  1212121

最后剩余1不能等于循环节

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5
 6 const int maxn = 1000005;
 7
 8 int next[maxn];
 9
10 void get(char *s) {
11     int l = strlen(s);
12     int j = 0, k = -1;
13     next[0] = -1;
14     while(j < l) {
15         if(k == -1 || s[j] == s[k]) {
16             next[++j] = ++k;
17         } else {
18             k = next[k];
19         }
20     }
21 }
22 char s[maxn];
23
24 int main() {
25     while(gets(s) ) {
26         if(strcmp(s,".") == 0) {
27             break;
28         }
29         get(s);
30         int ans = 1;
31         int l = strlen(s);
32         if(l % (l - next[l]) == 0) {
33             ans = l / (l - next[l]);
34         }
35         printf("%d\n", ans);
36     }
37 }

时间: 2024-08-08 13:55:57

poj2406(kmp next数组)的相关文章

HDOJ3336 Count the string 【KMP前缀数组】+【动态规划】

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4212    Accepted Submission(s): 1962 Problem Description It is well known that AekdyCoin is good at string problems as well as n

字符串匹配KMP next数组的理解

#include<cstdio> #include<cstring> void getNext(int *Next,char* src){ int i,j; Next[0]=-1; i=0; j=-1; int N=strlen(src); while(i<N-1){ if(j==-1||src[i]==src[j]){ ++i; ++j; Next[i]=j; }else{ /* 理解难点:假设已经存在Next:假设是两个字符串在进行比较. 1. a)现在有两个字符串 sr

POJ2406 Power Strings(KMP,后缀数组)

这题可以用后缀数组,KMP方法做 后缀数组做法开始想不出来,看的题解,方法是枚举串长len的约数k,看lcp(suffix(0), suffix(k))的长度是否为n- k ,若为真则len / k即为结果. 若lcp(suffix(0), suffix(k))的长度为n- k,则将串每k位分成一段,则第1段与第2段可匹配,又可推得第2段与第3段可匹配……一直递归下去,可知每k位都是相同的,画图可看出匹配过程类似于蛇形. 用倍增算法超时,用dc3算法2.5秒勉强过. #include<cstdi

poj2406 kmp 求最小循环字串

Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 47748   Accepted: 19902 Description Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "

poj2406 KMP

kmp简单题 找循环节.由于KMP的next[]数组,所以可以考虑最后一组的情况,及next[n]的值:n-next[n]的值表示一个循环节. 如果n%(n-next[n])!=0表明该循环不成立.不然就是直接得到. #include<stdio.h> #include<string.h> #define maxn 1000010 int next[maxn]; char s[maxn]; void getnext() { int j,k,len=strlen(s); j=0; k

POJ-3450 Corporate Identity (KMP+后缀数组)

Description Beside other services, ACM helps companies to clearly state their "corporate identity", which includes company logo but also other signs, like trademarks. One of such companies is Internet Building Masters (IBM), which has recently a

POJ2406 KMP算法

POJ2406 问题重述:给定字符串s0,记连续的k个s前后相连组成的s0s0...s0为s0^k.输入字符串S,求最大的k,使得S = s0^k. 问题分析: 1.采用kmp算法求出前缀函数 prefix[i] (i = 1,2,... n, n = length(S)). 2.假如n - prefix[n]能够整除n, 则S能表示为k = n / (n - prefix[n])个连续s0,且k此时取到最大值 3.否则, S不能表示为连续的s0的形式, k = 1. AC代码: 1 //Mem

[hdu3336]kmp(后缀数组)

题意:求字符串s的所有前缀出现次数之和. http://www.cnblogs.com/jklongint/p/4446117.html 思路:用kmp做,简单且效率高.以前缀结尾的位置分类,令dp[i]为以结尾位置在i的前缀数量,那么dp[i] = cnt(j)(j~i是前缀),而由kmp的next函数的转移性质,可得如下递推方程:dp[i] = dp[next[i]] + 1,把这个递推式不断展开,也就是i = next[i]不断迭代,那么+1的个数就是dp[i] = cnt(j)(j~i是

POJ 2406 KMP/后缀数组

题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就能求出循环次数. #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<str