【Python 3】回溯法解九数字问题

问题再现

求一个九位数M,已知M的各位数由不重复的1\sim 9组成,对于m \in \begin{Bmatrix} 2, 3, 4, \cdots , 9 \end{Bmatrix},数M左侧的m位数都是m的倍数。


解题思路

左侧m位数必须是m的倍数,那么我们能否使用回溯法:从左侧开始,每次向右确定1位数,若从某一位数开始无法找到满足条件的前m位数,则向左删除最后一位数并尝试其他值?这样,我们可以减少“无脑枚举”产生的大量无用值,更快地得到结果。


算法示例

def check(prev_nums: list, number: int) -> bool:
    ''' 判断当前数位是否满足题目要求 '''

    # 当前数位的数字不能存在于前序数位中
    is_contained = (str(number) not in prev_nums)

    # 前k位数必须能被k整除
    is_zero = (
        (10 * int(''.join(prev_nums)) + number) % len(prev_nums) == 0
    )

    # 同时满足以上2个条件才为真
    return (is_contained and is_zero)


def search_num(prev_nums=['0']):
    ''' 递归搜索数值 '''

    # 遍历数字1~9
    for k in range(1, 10):
        # 检查是否满足要求
        if check(prev_nums, k):
            # 追加此数值
            prev_nums.append(str(k))

            # 如果已经求出了指定位数且满足条件的要求
            if len(prev_nums) - 1 == 9:
                # 返回最终的k位数
                return int(''.join(prev_nums))
            else:
                # 否则继续检索下一位
                temp = search_num(prev_nums)

                # 如果下一位存在可行数值
                if temp is not None:
                    # 返回下一位的检索结果
                    return temp

    # 当前数位没有可行结果,移除上一位,重新检索
    prev_nums.pop()


if __name__ == "__main__":
    ''' 主函数 '''
    print(search_num())

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

️是纱雾酱哟~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值