【NC15291】幸运数字Ⅱ

题目

幸运数字Ⅱ

枚举,分块

思路

由题意可知在范围 [ 1 , 1 0 9 ] [1,10^9] [1,109] 内的幸运数字个数其实是很少的,这可以通过枚举得到,枚举又可分为递归和迭代,这里由于只有两种数字 4 , 7 4,7 4,7,恰好对应二进制的 0 , 1 0,1 0,1,所以通过迭代法来枚举比较合适。枚举之后会得到一个幸运数字数组 r e s res res,这里面从小到大地存放了在范围 [ 1 , 1 0 9 ] [1,10^9] [1,109] 内的幸运数字。

但是题目要求的并不是幸运数字本身,而是给定 l , r l,r lr,求出 n e x t ( l ) + n e x t ( l + 1 ) + . . . + n e x t ( r − 1 ) + n e x t ( r ) next(l) + next(l + 1) + ... + next(r - 1) + next(r) next(l)+next(l+1)+...+next(r1)+next(r)

可以知道,如果某个数 x x x 落在了幸运数区间 [ a , b ] [a,b] [a,b] 中,那么 n e x t ( x ) + ⋯ + n e x t ( b ) = ( b − x + 1 ) ∗ b next(x)+\dots+next(b)=(b-x+1)*b next(x)++next(b)=(bx+1)b,实质上这些幸运数将 n e x t ( l ) + n e x t ( l + 1 ) + . . . + n e x t ( r − 1 ) + n e x t ( r ) next(l) + next(l + 1) + ... + next(r - 1) + next(r) next(l)+next(l+1)+...+next(r1)+next(r) 分成了多个块,我们只需要枚举每个块,然后利用乘法即可计算出结果。

不幸的是这道题并没有要求对结果取模,所以答案可能很大(超出了长整型)。

如果使用 c / c + + c/c++ c/c++ 的话,需要手动模拟大整数的乘法和加法,实在太烦。为了方便,这里使用 P y t h o n Python Python

代码

res = []

# 获取所有幸运数字
def get_fnums():
    for i in range(1, 12):
        for j in range(0, 1 << i):
            t = 0
            for p in range(0, i):
                if (j >> p) & 1:
                    t = t * 10 + 7
                else:
                    t = t * 10 + 4
            res.append(t)


def solve(l, r):
    get_fnums()
    res.sort()
    ans = 0
    j = 0
    # 首先找到第一个大于等于l的幸运数字,可以用二分,但意义不大
    for i in range(0, len(res)):
        if res[i] >= l:
            j = i
            break
    # 如果l,r属于同一个块,则需要特殊处理
    if r <= res[j]:
        return (r - l + 1) * res[j]
    # 如果不是同一个块,则需要累加多个块
    ans += (res[j] - l + 1) * res[j]
    for i in range(j + 1, len(res)):
        if res[i] < r:
            ans += (res[i] - res[i - 1]) * res[i]
        else:
            ans += (r - res[i - 1]) * res[i]
            break
    return ans


if __name__ == "__main__":
    tmp = input().split(" ")
    print(solve(int(tmp[0]), int(tmp[1])))
  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木又可可

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

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

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

打赏作者

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

抵扣说明:

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

余额充值