试题 历届试题 子串分值和【第十一届】【省赛】【B组】

这里说明一下我的做题思路:首先该题对于我来说有一定的难度, 我一开始的想法如下

#include<bits/stdc++.h>

using namespace std;

int check(string str)//计算分值
{

}

int main()
{
	int sum=0;
	string str2;
	string str1;
	cin>>str1;
	for(int i=0;i<str1.length();i++)//双重循环
	{
		str2=str1[i];
		for(int j=i+1;j<str1.length();j++)
		{
			
			sum+=check(str2);//计算对应字串的分值 
			str2+=str1[j];//模拟样例分析一个一个字符加上去
		}
		str2.clear();
		//清空 
	}
	return 0;
}

可惜最后也是未能写出完整代码,最后和这道题耗了将近一个小时,还是上网找了题解来看才有了新思路,下面介绍两种解题思路:

1.暴力法(无法通过全部样例,会超时!)

  • 定义变量】用一个字母表存储每个字符出现的次数,用num存储以i(0<= i < 字符串长度)开始的子串的f值,用sum存储子串f值的和。(字母表和num每次 i 改变后要重置!)
  • 双重循环】子串的起点为 i(0<= i < 字符串长度),固定起点,终点从起点开始向后移动,每次移动会有一个新的字符增加,我们给相应的字母表中该字符对应的元素elem+1,然后我们就可以根据该元素的值判断当前子串的f值sum,若elem = 1,说明新增一个恰好只出现一次的字符,则num++;然后sum+=num即可。
  • 得出结果】循环结束后,sum值其实就出来了,输出即可。
#include <iostream>
#include <vector>
#include <string>
#include "string.h"
#include <algorithm>
using namespace std;
 
int main()
{
	string str;
	cin >> str;
	long long len = str.length();
	long long alphabet[27], num, sum =0;
	for (long long i = 0; i < len; i++)//子串起点
	{
		num = 0;
		memset(alphabet, 0, sizeof(alphabet));
		for (long long j = i; j < len; j++)
		{
			int k = str[j] - 'a';    
			alphabet[k]++;    
			
			if (alphabet[k] == 1)//新增一个恰好只出现一次的字符
				num++;

			sum += num;
		}
	}
	cout << sum;
	return 0;
}

2.计算贡献值法

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
char s[N];
ll f[N];    //预处理会爆int
int last[30];
int main(){
    scanf("%s",s+1);
    int n = strlen(s+1);
    ll ans = 0;
    //预处理没有任何重复的情况;
    for(int i=1;i<=n-i+1;i++)f[i] = f[n-i+1] = (n-i+1)*(ll)i; //注意乘的时候一定要转long long
    //统计总贡献,并去重
    for(int i = 1;i<=n;i++){
        int t = s[i]-'a';
        if(!last[t]){    //判断有无重复部分
            ans += f[i];
        }else{
            ans += f[i] - f[i]/i*last[t]; //减去重复部分;
        }
        last[t] = i; //记录当前字母最后出现位置
    }
    printf("%lld",ans);
    return 0;
}

以上笔记分别借鉴于(1条消息) 【2020蓝桥杯省赛】【字符串】子串分值(详解!)(两种解法)_NOT_TODAY1的博客-CSDN博客_蓝桥杯子串分值和(1条消息) 十一届蓝桥杯 子串分值和(一看就会)_littletomorrow的博客-CSDN博客_蓝桥杯子串分值和

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZZZWWWFFF_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值