Lanqiao Cup daily update 002 ZigZag points

original title

Title description
For a string S, we define the score fs of S as the number of characters that appear exactly once in s, for example, f(aba)=1, f(abc)=3, f(aaa)=0. Now given a string S0-n-1, please calculate the sum of all non-empty substrings of S.
Input description
Input a line containing a string S composed of lowercase letters
Output description
Output an integer representing the answer Input
and output sample
Input
ababc
output
21

analyze

  1. Take a chestnut:
    insert image description here

  2. Violent traversal will time out

  3. The method that will not time out: 考虑每个字符串最多能贡献几分
    the ideas and codes are very simple, let's take a look
    insert image description here

Main points:

  1. 对输入的字符串的头尾进行补充, for unified processing, it is also the character for judging termination.
  2. Consider the contribution score of each character, take the first character as an example, move left and right, add one point for each space moved, the cutoff condition is:遇到下一个a,或者遇到终止字符。
  3. The left side of the character is scored as the number of left moves, and the right side of the character is scored as the number of right moves, 本字符贡献得分为左右相乘.

code + comments

s = input()
# 对输入的字符串的头尾进行补充,为了统一处理。
# 0是判断终止的字符,同时保证了序号和索引的统一,第一个字符对应的索引就是1
s = "0" + s + "0"
length = len(s)


def find(i):
    # 左下标为当前位置左移一个
    left = i - 1
    # 右下标为当前位置右移一个
    right = i + 1
    # 遇到下一个相同字符,或者遇到终止字符就停止,没遇到就继续移动
    while left != 0 and s[left] != s[i]:
        left -= 1
    # 计算左得分公式为当前遍历对象下标-左下标
    left_score = i - left
    while right != length - 1 and s[right] != s[i]:
        right += 1
    # 计算右得分公式为右下标-当前遍历对象下标
    right_score = right - i

    # 当前遍历对象得分为左得分乘以右得分
    score = left_score * right_score
    return score


# 从第一个字符开始遍历到倒数第二个,倒数第一是补充的0
# 对每一个被遍历对象执行查找分数操作
# 对所有对象的分数转为列表并求和
print(sum([find(i) for i in range(1, length - 1)]))

Paid consultation

WeChat: x15511371025
QQ: 1142926171

Guess you like

Origin blog.csdn.net/cvxiayixiao/article/details/129945050