1. 问题描述:
给定一个由数字组成的字符串 s,请你计算能够被 4 整除的 s 的子串数量子串可以包含前导 0,例如,如果 s 为 124,则满足条件的子串有 4 个:12,4,24,124;如果 s 为 04,则满足条件的子串有 3 个:0,4,04。
输入格式
一个由数字组成的字符串 s
输出格式
一个整数,表示满足条件的子串数量
数据范围
前 4 个测试点满足 1 ≤ |s| ≤ 10
所有测试点满足 1 ≤ |s| ≤ 3 × 10 ^ 5
输入样例1:
124
输出样例1:
4
输入样例2:
04
输出样例2:
3
输入样例3:
5810438174
输出样例3:
9
来源:https://www.acwing.com/problem/content/description/4429/
2. 思路分析:
分析题目可以知道这道题目考察的其实是小学数奥的知识点:一个数 n 能够被 4 整除的充分必要条件是:4 能够整除 n 的末两位,所以只需要看末两位即可,对于只有一位数的情况特判即可,然后我们需要考虑如何枚举才可以枚举出所有的方案,我们可以枚举右端点 i,对于当前的右端点 i,判断第 i - 1 位和第 i 位构成的两位数是否可以被 4 整除,如果可以被 4 整除那么 0~i-1与 i 位构成的总共有 i 种子串都是可以被 4 整除的,枚举每一个右端点就可以计算出所有的方案数目:
3. 代码如下:
python:
class Solution:
def process(self):
s = input()
res = 0
for i in range(len(s)):
if int(s[i]) % 4 == 0:
res += 1
if i and int(s[i - 1: i + 1]) % 4 == 0:
res += i
print(res)
if __name__ == '__main__':
Solution().process()
go:
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func run(r io.Reader, w io.Writer) {
in := bufio.NewReader(r)
out := bufio.NewWriter(w)
// 将缓存数据写入到标准输出中
defer out.Flush()
var (
s string
res int
)
fmt.Fscan(in, &s)
for i := 0; i < len(s); i++ {
// s[i] 存储的是ascii值, 因为只是判断是否能够被4整出所以直接使用ascii值判断也可以
if s[i]%4 == 0 {
res += 1
}
if i > 0 && (s[i-1]*10+s[i])%4 == 0 {
res += i
}
}
fmt.Fprintln(out, res)
}
func main() {
run(os.Stdin, os.Stdout)
}