HDU-1358 Period 字符串问题 KMP算法 求最小循环节

题目链接:https://cn.vjudge.net/problem/HDU-1358

题意

给一个字符串,对下标大于2的元素,问有几个最小循环节

思路

对每个元素求一下minloop,模一下就好

提交过程

TLE maxn没给够
AC

代码

#include <cstring>
#include <cstdio>
const int maxm=1e6+20;
char P[maxm];
int fail[maxm];
void getFail(int m){
    fail[0]=fail[1]=0;
    for (int i=1; i<m; i++){
        int j=fail[i];
        while (j && P[j]!=P[i]) j=fail[j];
        fail[i+1]=((P[i]==P[j])?j+1:0);
    }
}

int main(void){
    int len, kase=0;
    while (scanf("%d", &len)==1 && len){
        scanf("%s", P);
        getFail(len);

        printf("Test case #%d\n", ++kase);
        for (int i=2; i<=len; i++){
            int maxloop=i-fail[i];
            if (maxloop!=i && i%maxloop==0) printf("%d %d\n", i, i/maxloop);
        }printf("\n");
    }

    return 0;
}
Time Memory Length Lang Submitted
78ms 6100kB 625 G++ 2018-08-02 10:46:24

原文地址:https://www.cnblogs.com/tanglizi/p/9408836.html

时间: 2024-12-14 03:59:21

HDU-1358 Period 字符串问题 KMP算法 求最小循环节的相关文章

(KMP 1.5)hdu 1358 Period(使用next数组来求最小循环节——求到第i个字符的循环节数)

题目: Period Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3813    Accepted Submission(s): 1862 Problem Description For each prefix of a given string S with N characters (each character has an A

hdu 3746 Cyclic Nacklace (KMP求最小循环节)

//len-next[len]为最小循环节的长度 # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int len; char a[100010]; int next[100010]; void Getnext() { int i=0,j=-1; next[0]=-1; while(i<=len) { if(j==-1||a[i]==a[j]) i

The Minimum Length - HUST 1010(求最小循环节)

题意:有个一字符串A(本身不是循环串),然后经过很多次自增变成AAAAA,然后呢从自增串里面切出来一部分串B,用这个串B求出来A的长度.   分析:其实就是求最小循环节.......串的长度 - 最大的匹配. 代码如下. =========================================================================================================== #include<stdio.h> #include<

hdoj3746(kmp算法的nex数组求最小循环节)

题目链接:https://vjudge.net/problem/HDU-3746 题意:给定一个字符串,问最少在两端添加多少元素使得整个字符串是呈周期性的. 思路: 应用到kmp中nex数组的性质,数组的最小循环节是L=len-nex[len],证明见http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html. 如果len%L==0,那么输出0. 否则输出L-len%L. AC代码: #include<cstdio> #inclu

poj2406--Power Strings(KMP求最小循环节)

Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 33178   Accepted: 13792 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 = "

next数组求最小循环节

最小循环节(长度)=len-next[len]; 证明: ----------------------- ----------------------- k    m      x      j       i 由上,next[i]=j,两段红色的字符串相等(两个字符串完全相等),s[k....j]==s[m....i] 设s[x...j]=s[j....i](xj=ji) 则可得,以下简写字符串表达方式 kj=kx+xj; mi=mj+ji; 因为xj=ji,所以kx=mj,如下图所示 ---

妙用next数组打表求最小循环节len

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int len; int n = 1000; int next[10000]; int f[50000]; char s[50000]; int Pow(int a, int b) { int res=1; while(b) { if(b&1) res=r

Hdu 1358 Period (KMP 求最小循环节)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1358 题目描述: 给出一个字符串S,输出S的前缀能表达成Ak的所有情况,每种情况输出前缀的结束位置和k. 解题思路: 打表算出next数组,然后对位置i求循环节,如果满足 i % (i - Next[i]) == 0 && Next[i] != 0,所对应的循环节(i - Next[i]), 循环次数是i / (i - Next[i]) 1 #include<cstdio> 2

HDU 1358 (求最小循环节)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358 题意:大概就是说给你一个字符串,然后找出能够循环的子串,输出子串某位置以及循环节的个数. 题解:用KMP算法得到next数组.然后,从i=2开始遍历,得到的i-next[i]为循环节大小. 如果对于i能够整除循环节,并且next数组的值不为0(如果为0,则代表不循环,但却可以整除) 则代表这个位置是可行的,位置为i,循环节个数为i/(i-next[i]) 代码如下: 1 #include<cs