博客
关于我
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/

    你可能感兴趣的文章
    PostgreSQL新手入门
    查看>>
    postgresql树状结构查询示例
    查看>>
    PostgreSQL流复制参数max_wal_senders详解
    查看>>
    postgresql流复制配置
    查看>>
    PostgreSQL清空表并保留表结构、清空数据库还原数据库为新建时的状态的方法
    查看>>
    PostgreSQL的 initdb 源代码分析之九
    查看>>
    PostgreSQL的安装与使用指南
    查看>>
    postman之参数化详解
    查看>>
    Postman入门到入土
    查看>>
    Postman如何做接口测试:如何导入 swagger 接口文档
    查看>>
    Postman如何做接口测试:如何导入 swagger 接口文档
    查看>>
    Qlik助力新西兰最大私人医院提高病患护理水平
    查看>>
    Postman如何生成接口文档
    查看>>
    Postman学习之常用断言
    查看>>
    postman居然是用electron开发的,我们来认识下这个框架吧
    查看>>
    postman常用公共函数
    查看>>
    Postman常见问题及解决方法
    查看>>
    PostMan怎样携带登录信息请求后台接口防止出现无法访问资源问题
    查看>>
    Postman接口传参案例
    查看>>
    postman接口功能测试
    查看>>