混境之地5(记忆化搜索)

问题描述

小蓝有一天误入了一个混境之地。

好消息是:他误打误撞拿到了一张地图,并从中获取到以下信息:

  1. 混境之地是一个 n⋅mn⋅m 大小的矩阵,其中第 ii 行第 jj 列的的点 hijhij​ 表示第 ii 行第 jj 列的高度。
  2. 他现在所在位置的坐标为 (A,B)(A,B) ,而这个混境之地出口的坐标为 (C,D)(C,D) ,当站在出口时即表示可以逃离混境之地。
  3. 小蓝有一个喷气背包,使用时,可以原地升高 kk 个单位高度。

坏消息是:

  1. 由于小蓝的体力透支,所以只可以往低于当前高度的方向走。
  2. 喷漆背包燃料不足,只可以最后使用一次。

小蓝可以往上下左右四个方向行走,不消耗能量。

小蓝想知道他能否逃离这个混境之地,如果可以逃离这里,输入 Yes ,反之输出 No 。

输入格式

第 11 行输入三个正整数 n,mn,m 和 kk , n,mn,m 表示混境之地的大小, kk 表示使用一次喷气背包可以升高的高度。

第 22 行输入四个正整数 A,B,C,DA,B,C,D ,表示小蓝当前所在位置的坐标,以及混境之地出口的坐标。

第 33 行至第 n+2n+2 行,每行 mm 个整数,表示混境之地不同位置的高度。

输出格式

输出数据共一行一个字符串:

  • 若小蓝可以逃离混境之地,则输出 Yes 。
  • 若小蓝无法逃离混境之地,则输出 No 。

样例输入1

5 5 30
1 1 5 5
3 20 13 12 11
19 17 33 72 10
12 23 12 23 9
21 43 23 12 2
21 34 23 12 1

样例输出1

Yes

样例解释1

从 (1,1)(1,1) 到 (5,5)(5,5) 的一条可行道路为:

  1. 在 (1,1)(1,1) 处使用喷气背包。
  2. (1,1)−>(1,2)−>(1,3)−>(1,4)−>(1,5)−>(2,5)−>(3,5)−>(4,5)−>(5,5)(1,1)−>(1,2)−>(1,3)−>(1,4)−>(1,5)−>(2,5)−>(3,5)−>(4,5)−>(5,5) 。

样例输入2

5 5 10
1 1 5 5
3 2 13 12 11
1 17 33 72 10
12 23 12 23 9
21 43 23 12 2
21 34 23 12 1

样例输出2

No

样例解释2

可以证明不存在一条路径可以从起点到达终点。

数据范围

对于所有测试样例, 1≤n,m≤10001≤n,m≤1000 , 1≤k,hij≤1061≤k,hij​≤106 。

运行限制

语言最大运行时间最大运行内存
C++1s512M
C1s512M
Java2s512M
Python33s512M
PyPy33s512M
Go3s512M
JavaScript3s512M

代码 

记忆化搜索,记忆化搜索体现(个人见解 当新坐标可以达到那么 现在这个坐标也可以到达,就记到了,如果新坐标四个方向上,不管是喷气,还是往低的方向走都不可达到那么说明真的就达到不了了) 

from functools import lru_cache
@lru_cache(maxsize=None)
def dfs(x,y,z):
##x 横坐标
##y 纵坐标
##z 是否使用了喷气包
    if x==C and y==D:
##   递归的出口是走到了C,走到了D 
        return True

##    对于在每个点是怎么做的呢 是为了走到C,D,要么消耗喷气包要么不消耗喷气包
##    对于每一次可以向上下左右四个方向走
    delta=[(0,-1),(0,1),(-1,0),(1,0)]
##   对于每个方向迭代一下
    for delta_x,delta_y in delta:
        xx,yy=x+delta_x,y+delta_y
##        n行m列 因此横坐标限制为n纵坐标限制为m
        if xx<0 or xx>=n or yy<0 or yy>=m:
##          如果发生了越界那么就跳过
            continue
##        新坐标比旧坐标低那么就可以走到新坐标
        if Map[xx][yy]<Map[x][y]:
##        往低于当前高度的地方走
            if dfs(xx,yy,z):
##            新坐标走到终点这里也可以走到终点
                return True
##            没有使用喷气z不变,可以使用
##          
        elif z==False and Map[xx][yy]<=Map[x][y]+k:
##            新坐标比旧坐标高,但是新坐标比旧坐标+喷气高度低
            if dfs(xx,yy,True):
##                新坐标走到终点这里也可以走到终点
                return True
##    for循环是探究一种情况 里面返回的是True False探究的是另一种情况,应该是和for并列的
    return False


n,m,k=map(int,input().split())
A,B,C,D=map(int,input().split())
A,B,C,D=A-1,B-1,C-1,D-1
##这里的Map是从0开始的
Map=[]
for i in range(n):
    Map.append(list(map(int,input().split())))
##dfs(0,0,False)
if dfs(A,B,False):
    print('Yes')
else:
    print('No')

    
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值