博客
关于我
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+Twisted+sqlanydb=ABORT()
    查看>>
    Python函数之返回值、作用域和局部变量
    查看>>
    Python+统计学 | 探索常用的数据分析统计分布
    查看>>
    python, selenium中用于切换帧的函数
    查看>>
    python函数
    查看>>
    python----线程、进程、协程的区别及多线程详解
    查看>>
    python---5
    查看>>
    python---使用celery分布式系统异步发送短信(云通讯)来验证登录
    查看>>
    python--003--百分号字符串拼接、format
    查看>>
    Python--10、线程
    查看>>
    Python--Redis实战:第四章:数据安全与性能保障:第4节:复制
    查看>>
    python--基本代码规范
    查看>>
    Python--抽象类接口类
    查看>>
    PYTHON--欧拉习题二
    查看>>
    python--高级应用总结
    查看>>
    python-520表白代码,我看谁说程序员不懂浪漫,送你几套表白代码,一步到位
    查看>>
    Python-Asyncio TypeError:无法在‘;等待‘;表达式中使用对象DICT
    查看>>
    Python-AttributeError:‘;dict&39;对象没有属性‘;序列‘;
    查看>>
    Python-ldap:是否可以在不显式写入密码的情况下进行绑定?
    查看>>
    python出现 unknown encoding: idna 的处理方法
    查看>>