博客
关于我
HDU——3374 String Problem (最大最小表示法+循环节+kmp)
阅读量:509 次
发布时间:2019-03-07

本文共 2912 字,大约阅读时间需要 9 分钟。

为了解决这个问题,我们需要找到生成的字符串中字典序最小和最大的字符串的Rank,以及它们在生成字符串中的出现次数。以下是详细的解决方案。

方法思路

  • 预处理字符串:使用KMP算法预处理字符串,计算每个位置的最长前缀和循环节。KMP算法可以在线性时间内处理长字符串,适合我们的需求。
  • 计算循环节:通过预处理得到的信息,可以确定字符串的循环节长度。循环节长度有助于确定生成字符串的重复情况。
  • 确定Rank
    • 最小Rank:从左到右寻找最小的字符移动方式,生成字典序最小的字符串。
    • 最大Rank:从右到左寻找最大的字符移动方式,生成字典序最大的字符串。
  • 计算出现次数:根据循环节长度和字符串重复情况,计算特定字符串在生成列表中的出现次数。
  • 解决代码

    import sysdef main():    str = sys.stdin.readline().strip()    len = len(str)    if len == 0:        print("0 0 0 0")        return        # 初始化next数组    nexts = [0] * len    j = -1    for i in range(len):        if j == -1:            nexts[i] = j        else:            j = nexts[j]            while j != -1 and str[i] != str[j]:                j = nexts[j]            if str[i] == str[j]:                j += 1            nexts[i] = j        # 计算最小循环节长度    min_cycle = len    for i in range(len):        if nexts[i] == len - 1:            min_cycle = min(min_cycle, len - (i + 1))        # 计算循环次数    cycle_len = len // min_cycle    if min_cycle == 0:        cycle_len = len        # 处理出现次数    # 计算所有生成字符串的出现次数    # 由于循环节可能有多个重复,出现次数是 len / (len - nexts[len-1])    # 这里假设循环节长度为min_cycle    # 出现次数为 len / min_cycle    # 但如果min_cycle是0,则出现次数为1    if min_cycle == 0:        appear_min = 1        appear_max = 1    else:        appear_min = len // min_cycle        appear_max = len // min_cycle        # 找到最小的Rank    def find_min_rank():        current = 0        j = 0        k = 0        min_rank = 0        while current < len and j < len:            if k == 0:                if j == current:                    min_rank += 1                    j += 1                else:                    current += 1            else:                if str[(current + k) % len] == str[(j + k) % len]:                    k += 1                else:                    current += 1                    if current > j:                        j = current                    k = 0        return min_rank        min_rank = find_min_rank()        # 找到最大的Rank    def find_max_rank():        current = 0        j = 1        k = 0        max_rank = 0        while current < len and j < len:            if k == 0:                if j == current:                    max_rank += 1                    j += 1                else:                    current += 1            else:                if str[(current + k) % len] > str[(j + k) % len]:                    k += 1                else:                    current += 1                    if current > j:                        j = current                    k = 0        return max_rank        max_rank = find_max_rank()        # 输出结果    print(f"{min_rank} {appear_min} {max_rank} {appear_max}")if __name__ == "__main__":    main()

    代码解释

  • 预处理字符串:使用KMP算法预处理字符串,计算每个位置的最长前缀,存储在nexts数组中。
  • 计算循环节长度:通过遍历nexts数组,找到字符串的最小循环节长度。
  • 计算出现次数:根据循环节长度,计算生成字符串的出现次数。
  • 找最小Rank:模拟左移过程,找到生成字符串中字典序最小的那个的Rank。
  • 找最大Rank:模拟逆向左移过程,找到生成字符串中字典序最大的那个的Rank。
  • 该方法确保了在处理大字符串时的高效性,能够在线性时间内完成预处理和寻找任务。

    转载地址:http://suqjz.baihongyu.com/

    你可能感兴趣的文章
    python 序列化操作
    查看>>
    Python 开发者,这 7 个 VS Code 插件极力推荐
    查看>>
    python手把手视频_硬货 | 手把手带你构建视频分类模型(附Python演练))
    查看>>
    python 录音左右声道_Python分离立体声wav压缩文件的左右声道
    查看>>
    Python 循环异或对文件进行加解密
    查看>>
    Python开发环境搭建(附VMware安装包及虚拟机环境)
    查看>>
    python 微信扫码登录_python实现微信第三方网站扫码登录(Django)
    查看>>
    Python 快速下载依赖
    查看>>
    python实现非参数统计的Cochran检验 (附完整源码)
    查看>>
    python 怎么验证是否安装成功 scrapy
    查看>>
    Python 手写数字识别-1
    查看>>
    Python实现接口自动化测试库(JSON与Requests)详解
    查看>>
    Python 手写数字识别-3-sklearn中的几种算法
    查看>>
    python实现SSIM和MSSSIM计算 (附完整源码)
    查看>>
    Python 打开文件注意事项
    查看>>
    python 批量修改文件名_python windows下批量修改文件名
    查看>>
    Python 抓取网页乱码问题 以及EXCEL乱码
    查看>>
    python 抓取网页内容
    查看>>
    python 按照当前日期创建文件
    查看>>
    Python 接口并发测试详解
    查看>>