• POJ-2406Power Strings-KMP+定理


    Power Strings

    题意:给一个字符串S长度不超过10^6,求最大的n使得S由n个相同的字符串a连接而成,如:"ababab"则由n=3个"ab"连接而成,"aaaa"由n=4个"a"连接而成,"abcd"则由n=1个"abcd"连接而成。

    定理:假设S的长度为len,则S存在循环子串,当且仅当,len可以被len - next[len]整除,最短循环子串为S[len - next[len]]

    例子证明:
    设S=q1q2q3q4q5q6q7q8,并设next[8] = 6,此时str = S[len - next[len]] = q1q2,由字符串特征向量next的定义可知,q1q2q3q4q5q= q3q4q5q6q7q8,即有q1q2=q3q4,q3q4=q5q6,q5q6=q7q8,即q1q2为循环子串,且易知为最短循环子串。由以上过程可知,若len可以被len - next[len]整除,则S存在循环子串,否则不存在。

    解法:利用KMP算法,求字符串的特征向量next,若len可以被len - next[len]整除,则最大循环次数n为len/(len - next[len]),否则为1。

    我的ac代码:

    #include <cstring>
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cstdio>
    
    using namespace std;
    string str;
    int len,nx[1000000+10];
    
    void getnext()
    {
        int j = 0,k = -1;
        nx[0] = -1;
        while(j<len)
        {
            if(k==-1||str[j]==str[k])
            {
                nx[++j]=++k;
            }else
            {
                k=nx[k];
            }
        }
    }
    
    int main(){
        while(cin>>str)
        {
            if(str[0]=='.')break;
            len = str.length();
            getnext();
            if(len % (len-nx[len]) == 0)
            {
                cout<<len/(len-nx[len])<<endl;
            }
            else cout<<1<<endl;
        }
        return 0;
    }
    skr
  • 相关阅读:
    设计模式1 设计模式概述
    关于jdk的配置
    搭建webpack项目框架
    移动乐淘day1
    前后端开发(2):浏览器与PHP程序的交互
    Ajax中post与get的区别
    Web前端:2、盒模型的组成
    Web前端:1、HTML&CSS概述及结构
    VMware11虚拟机安装Redhat6.5视频演示
    VMware虚拟机中安装Linux系统步骤(Redhat6.5)
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8424464.html
Copyright © 2020-2023  润新知