【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;i<=n;i++){
        while(j&&s[i]!=s[j+1])j=fail[j];
        if(s[i]==s[j+1])++j;
        fail[i]=j;
    }
}

void read_and_parse(){
    scanf("%s",s+1);
    get_fail();
}

void solve(){
    for(int i=2;i<=n;i++)
        if(i%(i-fail[i])==0&&i/(i-fail[i])>1)
            printf("%d %d\n",i,i/(i-fail[i]));
    puts("");
}

int main(){
    while(scanf("%d",&n)&&n){
        printf("Test case #%d\n",++kase);
        read_and_parse();
        solve();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/wzj-xhjbk/p/9859388.html

时间: 2024-10-31 09:57:45

【POJ1961】最短周期串/最大周期 kmp的相关文章

uva 1328 - Period (周期串的判断 kmp)

题意:给一个长为n的字符串,问字符串的前缀是不是周期串,如果是周期串,输出前缀的最后一个字母的位置和最短周期 思路:kmp字符串匹配的性质运用. 对于前i个字符,如果f[i]不等于零,说明在此字符串的前缀中,有一部分[0,f[i]]和本字符串[i-f[i],i]的这一部分是相同的.如果这i个字符组成一个周期串,那么错开的一部分[f[i],i]恰好是一个循环节.(换句话说,如果满足f[i]不等于零 && [f[i],i]是循环节这两点,就可以说明前i个字符组成一个周期串) code: #in

算法篇——最小周期串

来源:<算法竞赛入门经典>例题5.1.3 题目:如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期.例如,abcabcabcabc以3为周期(注意,它也以6和12为周期).输入一个长度不超过80的串,输出它的最小周期. 样例输入:HoHoHo 样例输出:2 分析:题目中说过,字符串可能会有多个周期.但因为只需求出最小的一个,可以从小到大枚举各个周期,一旦符合条件就立即输出. 源码: #include<stdio.h> #include<string.h

UVa455 周期串

题目描述:给一个字符串,找它的重复周期 思路: 假设周期从1~N,依次看是否能成为该字符串的重复周期.需要注意: 1.若周期串没有周期,其重复周期就是本身长度N 2.假设的周期k如果不能被N整除,自然就不是周期,不必考虑 3.N长的字符串等分成k长的子部,找每一个k长子部对应位置的字符是否相等即可 代码: 1 #include <stdio.h> 2 #include <string.h> 3 int main() 4 { 5 int N; 6 char s[100]; 7 sca

uva 周期串(求模分组)

/*本题题意求出周期串的最短长度:eg : hohoho 那么此周期串的长度可以为2 (ho) 同时也可以为 6(hohoho)  最短长度当然就是2本题思路:    求出周期串, 必然存在一个周期, 设定一个循环, i代表周期的长度,从1递增,最长的长度为字符串的长度 s.size(), 通过周期 将 字符串分组分组的字符串长度必须为整数, 因此只用考虑整数长度的字符串, 如果存在字符串所有分组都与第一组的字符相同, 那么此时就满足题意要求,输出对应的的周期长度 也就是最短的周期串长度, 本题

【周期串】NYOJ-1121 周期串

[题目链接:NYOJ-1121] 例如:abcabcabc 该字符串的长度为9,那么周期串的长度len只可能为{1,3,9},否则就不可能构成周期串. 接下来,就是要在各周期间进行比较.描述不清...自己走一遍就懂了. 1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int MAXN = 202; 5 char s[MAXN]; 6 int main(){ 7 while((cin &g

周期串-java

import java.util.Scanner;/** * 周期串 * @author NEU-2015 * */public class Demo {    public static void main(String[] args) {        Scanner input = new Scanner(System.in);        String str = null;        boolean flag = true;          while (input.hasNe

[华为机试练习题]1.周期串问题

题目一[周期串问题] 如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期.例如,abcabcabcabc以3为周期(注意,它也可以6和12为周期,结果取最小周期3).字符串的长度小于等于100,由调用者保证. 接口说明 原型: int GetMinPeriod(char *inputstring); 输入参数: char * inputstring:字符串 返回值: int 字符串最小周期 代码一 /*-----------------------------------

HDU 1358 (所有前缀中的周期串) Period

题意: 给出一个字符串,在所有长度大于1的前缀中,求所有的周期至少为2的周期串,并输出一个周期的长度以及周期的次数. 分析: 有了上一题 HDU 3746 的铺垫,这道题就很容易解决了 把next求出来,然后逐个判断即可. 1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 1000000 + 10; 5 char p[maxn]; 6 int n, next[maxn]; 7 8 void get_next(

算法竞赛入门经典 5.1.3 周期串

5.1.3  周期串 如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以为周期.例如,abcabcabcabc以3为周期(注意,它也以6和12为周期).输入一个长度不超过80的串,输出它的最小周期. 样例输入:HoHoHo 样例输出:2 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char s[100]; sca