华为OD机试-不包含101的数字 python 大家看看还能怎么优化呢
小明在学习二进制时,发现了一类不含 101的数,也就是:
将数字用二进制表示,不能出现 101 。
现在给定一个整数区间 [l,r] ,请问这个区间包含了多少个不含 101 的数?
输入描述:
输入的唯一一行包含两个正整数 l, r( 1 ≤ l ≤ r ≤ 10^9)。
输出描述:
输出的唯一一行包含一个整数,表示在 [l,r] 区间内一共有几个不含 101 的数。
样例
样例一:
输入
1 10
输出
8
样例解释
区间 [1,10] 内, 5 的二进制表示为 101 ,10的二进制表示为 1010 ,因此区间 [ 1 , 10 ] 内有 10−2=8 个不含 101的数。
样例二:
输入
10 20
输出
7
样例解释
区间 [10,20] 内,满足条件的数字有 [12,14,15,16,17,18,19] 因此答案为 7。
以下是我考试是用的代码,但通过率只有50%(时间复杂度过高),有没有大佬知道怎么优化
myLst = input().split()
x = int(myLst[0])
y = int(myLst[1])
count = y - x + 1
for i in range(x, y+1):
if '101' in bin(i):
count-=1
print(count)
看大佬用数位动态规划写的
left, right = map(int, input().split())
def dp(num):
# 将数字转化为二进制数组
binaryNums = list(map(int, bin(num)[2:]))
binaryDp = [[[0]*2 for _ in range(2)] for _ in range(len(binaryNums))]
return search(0, True, binaryDp, binaryNums, 0, 0)
def search(p, flag, binaryDp, binaryNums, pre, prepre):
# 边界条件,二进制数位数已经达到最高
if p == len(binaryNums):
return 1
# 如果不是第一次递归且已经计算过,直接返回结果
if not flag and binaryDp[p][pre][prepre] != 0:
return binaryDp[p][pre][prepre]
# 如果是第一次递归或者需要继续递归,则继续计算
index = binaryNums[p] if flag else 1
count = 0
for i in range(index+1):
# 如果出现 101,则直接跳过
if i == 1 and pre == 0 and prepre == 1:
continue
count += search(p+1, flag and i==index, binaryDp, binaryNums, i, pre)
# 如果不是第一次递归,则将结果存储到数组中
if not flag:
binaryDp[p][pre][prepre] = count
return count
print(dp(right) - dp(left-1))