程序员的算法趣题|程序员的算法趣题Q49: 欲速则不达
目录
1. 问题描述
2. 解题分析
3. 代码及测试
4. 后记
1. 问题描述
文章图片
2. 解题分析 本题是要找最长路径,应该广度优先搜索和深度优先搜索都可以。本文先考虑深度优先搜索。
本题与以前的类似的题目的区别在于约束条件的不同,比如说之前有类似的题目的约束条件是不能重复通过一条边,或者路线不能交叉,等等。本题的约束条件是在同一条直线上不能移动两次。因此在深度优先搜索过程中需要记录当前搜索路径中每条直线上已经移动过的次数,并结合边界条件下来确定从当前位置出发的下一步可能的移动方向。
文章图片
移动网格如上图所示,以n和m分别表示纵向宽度和横向长度,出发点坐标为(0,0),目标点坐标为(n,m)。横向和纵向分别有(n+1)条直线和(m+1) 条直线,分别用H和V表示(n+1)条横线和(m+1)条纵线已经移动过的次数。
深度优先搜索算法流程如下:
文章图片
最后,将curpos初始化为(0,0),steps初始化0,H和V分别初始化为适当size的全零数组,然后调用dfs()到最终退出后所得到的maxsteps即为所求结果。在以下代码实现中,maxsteps指定为全局变量,这样避免了参数传递的麻烦。
以上流程中,“还原H和V” 比较容易忘记,这个相当于函数递归调用退回时的退栈处理。只不过递归调用的退栈处理是编译器进行了自动管理。但是如果像steps那样的传递的话,由于没有更新当前递归层次的值,所以就不需要还原处理。
3. 代码及测试
# -*- coding: utf-8 -*-
"""
Created on Sat Oct9 07:12:37 2021@author: chenxy
"""# import sys
import time
fromcollections import dequen = 5
m = 6
target = (n,m)
maxsteps = 0
H = (n+1)*[0]
V = (m+1)*[0]def dfs(curpos, H, V, steps):
# print(curpos, H, V, steps)
global maxsteps
if curpos == target:
if maxsteps < steps:
maxsteps = steps
# Up trial
if curpos[0] > 0 and V[curpos[1]] < 2:
nxtpos = (curpos[0]-1, curpos[1])
V[curpos[1]] = V[curpos[1]] + 1
dfs(nxtpos, H, V, steps+1)
V[curpos[1]] = V[curpos[1]] - 1
# Down trial
if curpos[0] < n and V[curpos[1]] < 2:
nxtpos = (curpos[0]+1, curpos[1])
V[curpos[1]] = V[curpos[1]] + 1
dfs(nxtpos, H, V, steps+1)
V[curpos[1]] = V[curpos[1]] - 1
# Left trial
if curpos[1] > 0 and H[curpos[0]] < 2:
nxtpos = (curpos[0], curpos[1]-1)
H[curpos[0]] = H[curpos[0]] + 1
dfs(nxtpos, H, V, steps+1)
H[curpos[0]] = H[curpos[0]] - 1
# Right trial
if curpos[1] < m and H[curpos[0]] < 2:
nxtpos = (curpos[0], curpos[1]+1)
H[curpos[0]] = H[curpos[0]] + 1
dfs(nxtpos, H, V, steps+1)
H[curpos[0]] = H[curpos[0]] - 1
returntStart= time.perf_counter()
dfs((0,0),H,V,0)
tCost= time.perf_counter() - tStart
print('n={0}, m={1}, maxsteps={2}, tCost = {3:6.3f}(sec)'.format(n,m,maxsteps,tCost))
运行结果:n=5, m=6, maxsteps=25, tCost =1.682(sec)
4. 后记 运行速度有点差强人意。
接下来看看用广度优先搜索策略是不是能够更快一些。
上一篇:Q48: 翻转得到交错排列
本系列总目录参见:程序员的算法趣题:详细分析和Python全解
【程序员的算法趣题|程序员的算法趣题Q49: 欲速则不达】
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量