程序员的算法趣题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 Oct  9 07:12:37 2021

@author: chenxy
"""

# import sys
import time
from   collections import deque

n = 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    
    return

tStart  = 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: 翻转得到交错排列

        下一篇:Q50: 完美洗牌

        本系列总目录参见:程序员的算法趣题:详细分析和Python全解

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

笨牛慢耕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值