zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    软件工程课程-助教自我介绍
    软件工程课程-课代表信息
    软件工程课程-课后作业
    小知识记录:第四篇
    小知识记录:第三篇
    小知识记录:第二篇
    小知识记录:第一篇
    dd命令和fio命令测试磁盘io性能
    horizon仪表盘安装
    OpenStack安装部署笔记
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8424464.html
Copyright © 2011-2022 走看看