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循环从左往右
那么每访问一个字符,次数++

当前串状态
alen = 1 ,a = 1
ablen = 2 ,a = 1, b = 1
abalen = 2 , a = 2, b = 1
abablen = 2 ,a = 2, b = 2
ababclen = 3 , a = 2, b = 2, c = 1

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

当前串状态
babca-- , len = 3 a = 1, b = 2, c = 1
abcb-- , len = 3 a = 1, b = 1, c = 1
bca-- , len = 2 a = 0, b = 1, c = 1
cb-- ,len = 1 a = 0, b = 0, c = 1

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

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

由于今天刚考完担心被查重系统误判,故放下图片,不放源码,同理,不保证代码正确:
在这里插入图片描述
在这里插入图片描述
补充一下,我尝试生成了一个长度为10的4 次方的数据运行代码,可以1s内出现答案,但是换成10的5次方的数据就不行了,而正常的暴力解法则对于10的3次方就是极限,10的四次方长度的字符串则运行不出结果.

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值