题目 2585: 蓝桥杯2020年第十一届省赛真题-子串分值和

时间限制: 1Sec 内存限制: 128MB 提交: 262 解决: 67

题目描述

对于一个字符串S,我们定义S 的分值 f(S) 为S中出现的不同的字符个数。例如f (”aba”) = 2,f (”abc”) = 3, f (”aaa”) = 1。 现在给定一个字符串S[0…n-1](长度为n),请你计算对于所有S的非空子串S[i…j], 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

阅读完题目之后,大家可以能想着用暴力写出算法,其实不然,那样算法会非常的复杂,复杂度过大,时间超限等。在这里,为了更加方便的解决此题,引入一种新的思想,叫做各元素的“贡献值”。接下来举个例子,详细的说明一下,何为“贡献值”。

举个非常通俗易懂的例子,一家有三口人,爸爸负责买菜,妈妈负责做菜,儿子负责洗碗。通过三个人的“贡献”才完成了吃饭这件事,也就是说,吃饭=爸爸买菜+妈妈做菜+儿子洗碗,通过三个元素的不同贡献才完成了某件事,这就是各元素的“贡献值”概念。

好了,引入正题。此题也亦是如此,要计算该字符串的各非空子串中不同字符个数的和。我们可以转换成各元素所“贡献值”,各元素贡献值累计起来,便是题的最终解。

关键题解:

通过案例我们发现,字符串ababc,第一个字符a的在 a,ab,aba,abab,ababc这五个字符串中做出了“贡献”,究竟是什么意思呢?就是第一个字符a,在 a,ab,aba,abab,ababc中影响了这五个字符串,使它们的字符种类数增加了1。所以第一个元素a的贡献值为5.

再关注第二个字符b,在ab,aba,abab,ababc,b,ba,bab,babc这八个字符串中做出了“贡献”,影响了这八个字符串,使它们的字符种类数增加了1。所以第二个元素b的贡献值为8.

接着再关注第三个字符a,在ba,bab,babc,a,ab,abc这六个字符串中做出了“贡献”,影响了这六个字符串,使它们的字符种类数增加了1。所以第三个元素a的贡献值为6.

再接着关注第四个字符b,在ab,abc,b,bc这四个字符串中做出了“贡献”,影响了这四个字符串,使它们的字符种类数增加了1。所以第四个元素b的贡献值为4.

最后关注最后一个字符c,在ababc,babc,abc,bc,c这五个字符串中做出了“贡献”,影响了这五个字符串,使它们的字符种类数增加了1。所以最后一个元素b的贡献值为5.

通过贡献值相加你会发现,每个元素的贡献值相加为28,这就是元素贡献值的问题!

那么,该怎样求解呢,如何写算法呢

从上图箭头所指地方为当前字符b,那么b会影响多少字符串呢,对于为什么黄色界限是这样画,是因为,在指针指向b的时候,它的左边周围范围不能有b(一旦有有b则无法影响字符串,就无法做出“贡献”),右边范围任意。

那么此时的b会影响什么呢,会影响b右边的b,bc,影响b左边的ab,abc这四个字符串,所以贡献值为5,其他的字符也亦是如此,如下;

字符串b将会影响b右边的b,ba,bab,babc,影响b左边的ab,aba,abab,ababc这八个字符串由此可写如下代码

import java.util.*;
	public class Main {
		public static void main(String[] args) {
			Scanner sc=new Scanner(System.in);
			String str=sc.next();
			long contribute=str.length();  // 索引为0的贡献度为字符长度
			long count=0L;
			for(int i=1;i<str.length();i++) {
				for(int j=i-1;j>=0;j--) {
					if(str.charAt(j)!=str.charAt(i)) {
						count++;
						if(j==0) {
							contribute+=((count+1)*(str.length()-i));
							count=0;
							break;
						}
					}
					else {
						contribute+=((i-j)*(str.length()-i));
						count=0;
						break;
					}
				}
			}
			System.out.println(contribute);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_49174867/article/details/123535938