2020.9.12 SSL普及组模拟(第1题)(字符串)
发布日期:2021-05-08 21:51:57 浏览次数:18 分类:精选文章

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

为了解决这个问题,我们需要找到由小写英文字母组成的字符串中包含子串“bear”的所有可能的子串对数。具体来说,我们需要计算满足条件的(i, j)对数,其中子串s[i...j]包含至少一个“bear”。

方法思路

  • 预处理:首先,我们遍历字符串,找到所有包含“bear”的位置,并将这些位置存储在一个数组中。
  • 检查子串:对于每个可能的子串(i, j),我们需要检查是否存在一个“bear”子串的位置k,使得i ≤ k ≤ j-3。为了高效地检查这一点,我们使用二分查找来确定是否存在这样的k。
  • 解决代码

    import bisect
    s = input().strip()
    bear_positions = []
    n = len(s)
    for k in range(n - 3):
    if s[k] == 'b' and s[k+1] == 'e' and s[k+2] == 'a' and s[k+3] == 'r':
    bear_positions.append(k + 1) # 转换为1-based索引
    count = 0
    for i in range(1, n + 1):
    for j in range(i + 3, n + 1):
    low = i
    high = j - 3
    left = bisect.bisect_left(bear_positions, low)
    right = bisect.bisect_right(bear_positions, high)
    if right > left:
    count += 1
    print(count)

    代码解释

  • 预处理阶段:我们遍历字符串,检查每个位置k是否是“bear”开始的位置。如果是,我们将k的位置(转换为1-based索引)存储在bear_positions数组中。
  • 检查子串阶段:对于每个可能的子串起始位置i和结束位置j,我们使用二分查找来确定是否存在一个k在bear_positions数组中,满足i ≤ k ≤ j-3。如果存在这样的k,我们计数加一。
  • 输出结果:最后,我们输出满足条件的(i, j)对数。
  • 这种方法通过预处理和二分查找,有效地减少了重复检查,提高了效率,使得在合理的时间内解决问题。

    上一篇:2020.9.12 SSL普及组模拟(第2题)(序列)(dp)
    下一篇:P6704 [COCI2010-2011#7] GITARA(栈)

    发表评论

    最新留言

    关注你微信了!
    [***.104.42.241]2025年03月23日 23时47分18秒