poj1961 kmp

题目大意,求这个字符串到i为止有多少个循环串;

int k = i-next[i];
if((i+1)%k == 0 && (i+1)!= k)
printf("%d %d\n", i+1, (i+1)/k);

这是代码的主要部分,求next数组的部分大家都知道,我来说说这部分的正确性;

例如一个字符串的第99为指向第96位,也就是说后4-99位和前1-96位是匹配的,就是说94到96与97到99是是匹配的;

而且91-94与94-96是匹配的。。。。。。。。。。。

一直可以推到最前面,以上就是正确性啦~

上代码

#include <iostream>
#include <string.h>
#include <map>
#include <stdio.h>
using namespace std;
const int maxa =1000005;
int next[maxa];
int vis[maxa];
int n;
void init_kmp(char str[])
{
memset(vis, 0, sizeof(vis));
next[0]=-1;
for(int i=1;str[i]!=0;i++)
{
int j= next[i-1];
while(str[j+1]!=str[i]&&j>=0)
j= next[j];
if(str[j+1] == str[i])
next[i] = j + 1;
else
next[i] = -1;
}
}
int main(){
char str[maxa];
int d =1;
while(scanf("%d", &n), n){
scanf("%s", str);
printf("Test case #%d\n", d++);
init_kmp(str);
for(int i = 0; i < n; i++){
int k = i-next[i];
if((i+1)%k == 0 && (i+1)!= k)
printf("%d %d\n", i+1, (i+1)/k);
}
printf("\n");
}
}

poj1961 kmp

时间: 2024-10-10 12:04:01

poj1961 kmp的相关文章

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[

POJ1961[KMP 失配函数]

Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 16776   Accepted: 8077 Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the

poj1961 Period kmp解决找字符串的最小循环节

/** 题目:poj1961 Period 链接:http://poj.org/problem?id=1961 题意:求从1到i这个前缀(2<=i<=N) ,如果有循环节(不能自身单独一个),输出前缀字符串长度以及最大的循环周期: 思路: 参考自:http://www.cnblogs.com/chenxiwenruo/p/3546457.html 定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0-len-next[len]-1]. (1)

poj1961 &amp; hdu 1358 Period(KMP)

poj 题目链接:http://poj.org/problem?id=1961 hdu题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358 Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether

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>

POJ1961 Period (kmp) 题解

Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 16462   Accepted: 7903 Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the

poj1961 Period(KMP)

C - Period Crawling in process... Crawling failed Time Limit:3000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1961 Appoint description: System Crawler (2016-05-10) Description For each prefix of a given str

【POJ1961】最短周期串/最大周期 kmp

引理:\(s[1,i]\) 具有长度为 \(len\) 的循环节的充要条件是:\(len\ |\ i,s[1,i-len]=s[len+1,i]\). 代码如下 #include <cstdio> #include <cstring> using namespace std; const int maxn=1e6+10; char s[maxn]; int n,kase,fail[maxn]; void get_fail(){ fail[1]=0; for(int i=2,j=0;

Codeforces 526D Om Nom and Necklace kmp+hash

题目链接:点击打开链接 题意: 给出长度为n的字符串,常数k 下面一个长度为n的字符串. 问: for(int i = 1; i <= n; i++){ 字符串的前i个字符 能否构成 形如A+B+A+B+A+B+A的形式,其中A有k+1个,B有k个 A和B是2个任意的字符串(也可以为空串) 若可以构成则输出1,否则输出0 } 思路: POJ1961 先用kmp求一个前缀循环节,. 我们观察 ABABABA => AB, AB, AB, A 所以前缀循环节有K个,而后面的A是尽可能地和AB长度接