蓝桥杯31天冲刺打卡(day26)

目录

​​​​​​1、子串分值(20年省赛) 

​​​​​​2、小数第n位(17年国赛)



​​​​​​1、子串分值(20年省赛) 

解析:

        用到尺取法(双指针),只要用指针找到相同的数的左右边界的位置以及当前数的位置,然后计算各个字母的贡献度并相加,即可求出答案。

        比如ababc中a在a、ab中有贡献,即为2=(0-(-1))*(2-0),b在ab、aba、b、ba中有贡献,即4=(1-(-1))*(3-1)……所以公式是(当前位置 - 左边与其相同字符且靠的最近的位置)*(左边与其相同字符且靠的最近的位置 - 当前位置)

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
string s;
LL sum;

int main() {
	cin>>s;
	for(int i=0; i<s.size(); i++) {
		char h=s[i];//标记该字符,找出左右边界
		int left,right;
		for(right=i+1; right<s.size(); right++)//右边界的相同点
			if(s[right]==h) break;
		for(left=i-1; left>=0; left--)//左边界的相同点
			if(s[left]==h) break;
		sum+=(i-left)*(right-i);
	}
	cout<<sum;
	return 0;
}

同年类似题:​​​​​​​

子串分值和

 

解析:同上,只需要改一下贡献度即可,依然是用指针找到相同数的位置,不过这次不需要两个指针来找左右边界,只需要一个指针找到之前的边界位置即可。

        比如:ababc的a在字串a、ab、aba、abab、ababc都有贡献,即5=5*1;b在ab、aba、abab、ababc、b、ba、bab、babc,即8=4*2;第二个a在ba、bab、babc、a、ab、abc,即6=3*2;第二个b在ab、abc、b、bc,即4=2*2;c在ababc、babc、abc、bc、c,即5=1*5

        所以可得公式(当前位置-左边与当前字符相同且靠得最近的位置)*(字串总长-当前位置)

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
LL sum;
string s;
int main() {
	cin>>s;
	int left;
	for(int i=0; i<s.size(); i++) {
		char c=s[i];
		for(left=i-1; left>=0; left--)
		if(c==s[left]) break;//找到左边相同点的位置
		sum+=(i-left)*(s.size()-i);
	}
	cout<<sum;
	return 0;
}


​​​​​​2、小数第n位(17年国赛)

 

解析:

        快速幂模板题,注意配出3位整数用于输出,我们还没推出公式时,可以得出(a*quick(10,n+2))/b%1000,用案例来说就是1000/8%1000=125(可以获得125),我们知道快速幂中需要%1个数才能保证不爆精度,所以这题同理,那么取模的这个数该咋找?我们将上式写成(x/y)%1000,模1000即取后三位数,设这个数为z,即(x/y)%1000=z。假如我们改成数,(10000/4)%1000=500,我们猜测一下两边同乘4就是10000%(4*1000)=500*4,发现是成立的,所以我们将上面的式子改为x % (y * 1000) = y * z(我也不知道为什么),然后%的数就是(y * 1000),这道题就大功告成了。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
LL a,b,n;

LL quick(LL x,LL y) {
	LL ans=1;
	while(y>0) {
		if(y&1) ans=(ans*x)%(b*1000);
		x=(x*x)%(b*1000);
		y/=2;
	}
	return ans;
}

int main() {
	cin>>a>>b>>n;
	cout<<(LL)((a*quick(10,n+2))%(b*1000)/b);//后面改成/b%1000也行
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_谦言万语

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

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

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

打赏作者

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

抵扣说明:

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

余额充值