在Leetcode等刷題網站刷題時,爲了方便少敲分號,我經常會選擇用python;但頭疼的是,同樣的算法有時候C++能過但python不能過,比如關於Python答題時報maximum recursion depth exceeded in comparison
,往往是因爲用了遞歸算法,當深度過深時被python虛擬機直接拒絕了。
舉例
牛客題目地址:https://www.nowcoder.com/practice/52f25c8a8d414f8f8fe46d4e62ef732c
題目描述
小多想在美化一下自己的莊園。他的莊園毗鄰一條小河,他希望在河邊種一排樹,共 棵。小多采購了 個品種的樹,每個品種的數量是 (樹的總數量恰好爲 )。但是他希望任意兩棵相鄰的樹不是同一品種的。小多請你幫忙設計一種滿足要求的種樹方案。
輸入描述:
第一行包含一個正整數 ,表示樹的品種數量。
第二行包含 個正整數,第 () 個數表示第 個品種的樹的數量。
數據範圍:
輸出描述:
輸出一行,包含 M 個正整數,分別表示第 i 棵樹的品種編號 (品種編號從1到 N)。若存在多種可行方案,則輸出字典序最小的方案。若不存在滿足條件的方案,則輸出"-"。
示例:
輸入
3
4 2 1
輸出
1 2 1 2 1 3 1
解題思路
這道題本身就是一個DFS加上剪枝,但是受限於python默認的最大遞歸深度,會出現某些數據爆函數棧的問題,而同樣的算法使用C++則不會有問題。例如:
N = int(input())
arr = list(map(int, input().split())) # sum(arr) = M
M, res = sum(arr), []
def dfs(a, m, prev_tree_class):
global res
if m == 0:
return True
for i in range(len(a)):
if a[i]*2 > m+1: # 減枝條件
return False # 當某一類樹剩餘數量大於坑位的一半時不可能滿足題意
tree_class = i+1
if a[i] > 0 and prev_tree_class != tree_class:
a[i] -= 1 # 種一棵
res.append(tree_class)
if dfs(a, m-1, tree_class):
return True
res.pop(-1) # 不滿足則回退
a[i] += 1
return False
# 字典序取小,則從第0類樹開始探測
print(" ".join(map(str, res)) if dfs(arr, M, 0) else "-")
解決方案
# 在開頭加上
import sys # python 默認遞歸深度不超過1000,做dfs會比C吃虧
sys.setrecursionlimit(10000000)# 手動修改深度