📜  门|门 IT 2005 |第 66 题(1)

📅  最后修改于: 2023-12-03 14:58:35.688000             🧑  作者: Mango

题目介绍:门|门 IT 2005 |第 66 题

该题目是门|门 IT 2005比赛中的第66题,是一道有趣的数学问题。

题目描述

给定一个整数n,找出小于等于n的所有正整数中,二进制表示不含连续的1的个数。

解题思路

这是一道数学题,需要使用到递归和位运算的知识。我们可以考虑从小到大依次求出满足条件的整数,以此来推导出大于n的整数是否满足条件。

具体思路如下:

  1. 如果 n < 3,那么小于等于n的所有整数中,二进制表示不含连续的1的个数为n本身,因为只有0和1两个数满足条件。
  2. 否则,我们可以将n的二进制表示分为两部分,一是最高位的1和它左边的0,二是剩余部分(若没有剩余,则为0)。
  3. 如果最高位的1后面一个位置是0,那么所有小于等于n的数中,以最高位的1开头的所有二进制表示都没有连续的1,因此我们只需要递归求解剩余部分的二进制表示总数即可。
  4. 如果最高位的1后面一个位置是1,那么对于所有小于等于n的数中,以最高位的1开头的二进制表示中,一定存在连续的1。因此,这部分二进制表示中,只需要考虑最高位为10开头或00开头的情况,而不用递归求解。
代码实现
def countBinary(num):
    # 小于3的情况
    if num < 3:
        return num + 1
    # 求出num的二进制表示
    binary = bin(num)
    # 最高位的1的位置
    pos = binary.rfind("1")
    # 求出最高位的1和它左边的0组成的数
    low = int(binary[2:pos], 2)
    # 求出剩余部分
    high = num - low - (1 << (pos - 1))
    # 如果最高位的1后面是0,递归求解剩余部分
    if high >> (pos - 2) == 2:
        return countBinary(low) + countBinary(high)
    # 否则只需考虑10和00开头的情况
    else:
        return countBinary(low) + countBinary((1 << (pos-1)) - 1)

以上就是解题思路和代码实现,可以通过此代码去获得满足条件的所有二进制表示的个数。