2020第11届蓝桥杯C++B组(不确保答案正确性,仅供参考)2020蓝桥试题 H: 子串分值和 (优化)

试题 H: 子串分值和
时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分
【问题描述】
对于一个字符串 S,我们定义 S 的分值 f(S ) 为 S 中出现的不同的字符个
数。例如 f(”aba”) = 2,f(”abc”) = 3, f(”aaa”) = 1。
现在给定一个字符串 S [0…n 1](长度为 n),请你计算对于所有 S 的非空
子串 S [i… j](0 ≤ i ≤ j < n),f(S [i… j]) 的和是多少。

【输入格式】

输入一行包含一个由小写字母组成的字符串 S。

【输出格式】

输出一个整数表示答案。

【样例输入】

ababc

【样例输出】

28

【样例说明】

子串 f值 a 1
ab 2
aba 2
abab 2
ababc 3
b 1
ba 2
bab 2
babc 3
a 1
ab 2
abc 3
b 1
bc 2
c 1

【评测用例规模与约定】
对于 20% 的评测用例,1 ≤ n ≤ 10;
对于 40% 的评测用例,1 ≤ n ≤ 100;
对于 50% 的评测用例,1 ≤ n ≤ 1000;
对于 60% 的评测用例,1 ≤ n ≤ 10000;
对于所有评测用例,1 ≤ n ≤ 100000。

思路:
以ababc为例
定义一个数组存放每个字母出现的次数,len表示不是0的字母的个数
第一次for循环从左往右
那么每访问一个字符,次数++

当前串 状态
a len = 1 ,a = 1
ab len = 2 ,a = 1, b = 1
aba len = 2 , a = 2, b = 1
abab len = 2 ,a = 2, b = 2
ababc len = 3 , a = 2, b = 2, c = 1

接下来,for循环从左到右,但是删除字符串最左边的值

当前串 状态
babc a-- , len = 3 a = 1, b = 2, c = 1
abc b-- , len = 3 a = 1, b = 1, c = 1
bc a-- , len = 2 a = 0, b = 1, c = 1
c b-- ,len = 1 a = 0, b = 0, c = 1

由此可见,两次循环下去只用O(2N)的时间求出来大量的需要累加的字符串

但是ababc中间的子串bab以及以此为基础的字串都没有被考虑到,所以此时,只需要在外层新加一层循环,l=0,r = str.length() ,只要l<r,就循环,然后l++,r- -,最后就能考虑到所有的情况
代码:

由于今天刚考完担心被查重系统误判,故放下图片,不放源码,同理,不保证代码正确:
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44378358/article/details/109134500