問題再現
求一個九位數,已知的各位數由不重複的組成,對於,數左側的位數都是的倍數。
解題思路
左側位數必須是的倍數,那麼我們能否使用回溯法:從左側開始,每次向右確定1位數,若從某一位數開始無法找到滿足條件的前位數,則向左刪除最後一位數並嘗試其他值?這樣,我們可以減少“無腦枚舉”產生的大量無用值,更快地得到結果。
算法示例
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())