洛谷 B4185 [中山市赛 2024] 倍数子串 题解

洛谷B4185倍数子串题解
该文章已生成可运行项目,

B4185 [中山市赛 2024] 倍数子串 题解

完整题目

B4185 [中山市赛 2024/科大国创杯小学组 2023] 倍数子串/子串

题目背景

本题题面为 2024 年中山市赛版本,在题面主人公上与 2023 年安徽省科大国创杯小学组略有区别。

题目描述

Jimmy 对数字有着异于常人的热爱。有一天,他随便写出来一个数字—— 04320 04320 04320,然后开始对着这个数字写写画画。他发现,从这个数字中随便选出连续的一段(Jimmy 把这个称为连续子串),有可能是 4 4 4 的倍数,例如 4 4 4 04 04 04 32 32 32 432 432 432 等;也有可能是 5 5 5 的倍数,例如 20 20 20 320 320 320 等。
Jimmy 的老师恰好路过此处,他向正沉迷于自己发现的 Jimmy 提了一个有趣的问题——给定一个指定的数字串,请问有多少连续子串是 4 4 4 或者 5 5 5 的倍数呢?
老师还特别提醒他:

  • 连续子串的开头可以是 0 0 0
  • 两个连续子串只要是从数字串中的不同位置选出来的,它们就>算是不同的;
  • 如果一个连续子串同时是 4 4 4 5 5 5 的倍数,应当只被计算一次哦!

输入格式

一行一个数字串,长度为 n n n

输出格式

一行一个整数,表示所有的连续子串中,为 4 4 4 或者 5 5 5 的倍数的数量。

输入输出样例 #1

输入 #1

04320

输出 #1

11

输入输出样例 #2

输入 #2

2000

输出 #2

9

说明/提示

样例解释 1

所有满足题意的连续子串分别为: 0 0 0 04 04 04 0432 0432 0432 04320 04320 04320 4 4 4 432 432 432 4320 4320 4320 32 32 32 320 320 320 20 20 20 0 0 0
其中有两个相同的 0 0 0,这是因为它们是从数字串中的不同位置选出来的(一个在开头处,一个在结尾处)。

数据范围

  • 对于 10 % 10\% 10% 的数据,保证 n = 1 n = 1 n=1
  • 对于 60 % 60\% 60% 的数据,保证 1 ≤ n ≤ 1 0 3 1 \leq n \leq 10^3 1n103
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 1 0 6 1 \leq n \leq 10^6 1n106

1. 读题

  • 其实关键句就一句:请问有多少连续子串是 4 或者 5 的倍数呢?
  • 0 也是 4 或者 5 的倍数。
  • 如果一个连续子串同时是 4 和 5 的倍数,应当只被计算一次

2. 解题思路

  • 逐一遍历字符串并进行判断,末尾是 0 或 5 的数为 5 的倍数,后两位能被 4 整除,为 4 的倍数。答案用变量 ans 记录。

3. 代码片段分析

  1. 遍历字符串:
for(int i=s.size()-1;i>=0;i--)
  1. 计算是否为 5 的倍数:
if(s[i]=='5'||s[i]=='0')//如果是 0 或 5,则为 5 的倍数。
  ans=ans+i+1;//累加。
  1. 计算是否为 4 的倍数:
		//减去字符 0 可以将字符转换为数字。 
	else if(((s[i]-'0')+(s[i-1]-'0')*10)%4==0){//判断末两位是 4 的倍数 
		ans=ans+i+1;
  1. 对于 4 的倍数需要特判

如果数字为 4 或 8 ,那么这个数也是 4 的倍数,但以其为末尾的数不一定是 4 的倍数,且以该数的这一位和上一位组成的十位数不一定为 4 的倍数,要特判。

1.if(s[i]=='2'||s[i]=='6')ans--;

2.if(s[i]=='4'||s[i]=='8')ans++;

4. AC 代码

代码片段中基本就是全部代码,如果你是这种情况,我只能引用一句 OI 界的名言:

十年 OI ⁡ \operatorname{OI} OI 一场空,不开 long long ⁡ \operatorname{long\hspace{1mm}long} longlong 见祖宗

有任何问题请指出,如果对你有帮助,点个赞再走吧!谢谢!

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

—海燕—

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

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

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

打赏作者

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

抵扣说明:

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

余额充值