华为OD机试-不包含101的数字
华为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))