振兴中华
小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:(也可参见p1.jpg)
从我做起振
我做起振兴
做起振兴中
起振兴中华
比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。
要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
解题(答案:35)
深度优先搜索(递归)
核心思想:对于正确路线可能的计数,每一个结点的计数值count是她所能前往的结点的count的和
0.结点(node: int)
在图map_str = '从我做起振我做起振兴做起振兴中起振兴中华'
中
每一个字都是一个结点,为了方便,我们用其在map_str中的下标表示
1.计数(count)
算法的目的是计数
计数的条件是成功走到‘华’
我们把对‘成功’的判断剥离开来(即保证每一步都正确)
到‘华’时,count+=1
if map_str[node] == '华':
count += 1
2.对‘正确’或‘成功’的判断
(1)判断依据
总:一句话result_str = '从我做起振兴中华'
分: 字与字之间都有判断
proper_order_dic = {
0: '从',
'从': '我',
'我': '做',
'做': '起',
'起': '振',
'振': '兴',
'兴': '中',
'中': '华'
}
懒得的打字的话
proper_order_dic = {0: '从'}
for i in range(len(result_str)-1):
proper_order_dic[result_str[i]] = result_str[i+1]
(2)判断需求
我们的需求除了“依据”proper_order_dic
外
还需要等式两边的值
被判断对象可以根据node化为map_str[node]
判断对象却要在递归时由上一步传入
于是设定变量tep, 初始默认为0(根据“依据”)
在每一“层”是设定next_tep = map_str[node]
并把它传入下一层dps(tep=next_tep)
(3)判断语句
if map_str[node] == proper_order_dic[tep]:
3.递归
核心:下一层的结点next_node
(1)结点间的的关系relation_lst = ['右', '下']
(2)在node上数值的变化的体现
relationship_dic = {
'右':1,
'下':5
}
(3)变化
for direction in relation_lst:
next_node = node+relationship_dic[direction]
(4)稍作限制(懒,为了少敲代码,这里加入了一部分主观判断,牺牲了一定的时间、空间复杂度,并不严谨)if next_node <= 19:
(5)传入下层count += dps(node=next_node, tep=next_tep)
(顺便计数)
完整代码
map_str = '从我做起振我做起振兴做起振兴中起振兴中华'
result_str = '从我做起振兴中华'
proper_order_dic = {0: '从'}
for i in range(len(result_str)-1):
proper_order_dic[result_str[i]] = result_str[i+1]
relation_lst = ['右', '下']
relationship_dic = {
'右':1,
'下':5
}
def dps(node, tep=0):
count = 0
if map_str[node] == '华':
count += 1
if map_str[node] == proper_order_dic[tep]:
next_tep = map_str[node]
for direction in relation_lst:
next_node = node+relationship_dic[direction]
if next_node <= 19:
count += dps(node=next_node, tep=next_tep)
return count
print(dps(node=0, tep=0))