day05 ,比2017那道题复杂了许多

题目描述

下图给出了一个迷宫的平面图,其中标记为1 的为障碍,标记为0 的为可 以通行的地方。 010000 000100 001001 110000 迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左、右四个方向之一。 对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫, 一共10 步。其中D、U、L、R 分别表示向下、向上、向左、向右走。 对于下面这个更复杂的迷宫(30 行50 列),请找出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。 请注意在字典序中D<L<R<U。

输入

maze.txt

见:http://oj.ecustacm.cn/problem.php?id=1455

分析

不仅要走迷宫,而且要记录如何走,而且字典序要最小。

采用 minn记录最小步数

用 ans记录每次如何走

字典序最小:直接将路径按字典序遍历的走

dp来记录到达某一步所需要的最短路径

题解

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

with open('maze.txt') as f:
    maze = f.readlines()

maze_list =[]
for i in maze:
    temp = []
    temp.extend(i.strip('\n'))
    maze_list.append(temp)

minn = 9999
ans = ''
visited = [[0 for _ in range(50)] for _ in range(50)] #是否访问过
direction = [[1, 0], [0, -1], [0, 1], [-1, 0]]
dp = [[9999 for _ in range(50)] for _ in range(50)]  #保存每一步的当前路数
vv = [0 for _ in range(1000)]
s = ['D', 'D', 'L', 'R', 'U'] 
def dfs(x, y, steps):
    global minn, ans
    if steps > minn:return
    if x == 29 and y == 49:
        if steps < minn:
            minn = steps
            tmp = ''
            for i in range(1, steps):
                tmp += s[vv[i]]
            ans = tmp
        return
    for i in range(1, 5):
        tx = x + direction[i-1][0]
        ty = y + direction[i-1][1]
        if tx < 0 or ty < 0 or tx > 29 or ty >49: #越界判断
            continue
        if visited[tx][ty] or maze_list[tx][ty] == '1':
            continue
        if steps + 1 > dp[tx][ty]:
            return
        dp[tx][ty] = steps + 1
        visited[tx][ty] = 1
        vv[steps] = i
        dfs(tx, ty, steps + 1)
        visited[tx][ty] = 0

dfs(0, 0, 1)
print(ans)