题目描述
下图给出了一个迷宫的平面图,其中标记为1 的为障碍,标记为0 的为可
以通行的地方。
010000
000100
001001
110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这
个它的上、下、左、右四个方向之一。
对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,
一共10 步。其中D、U、L、R 分别表示向下、向上、向左、向右走。
对于下面这个更复杂的迷宫(30 行50 列),请找出一种通过迷宫的方式,
其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。
请注意在字典序中D<L<R<U。
输入:
很明显,这是一个求最短路径的题目。这里用到的方法是 广度优先索搜。
由于在字典序中D<L<R<U,因此如果在有很多方向可以走的情况下,优先考虑往下走,走不通了在往左走,依次类推。
data = '''01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000'''
data_array = []
data_array.append([1]*52)
for i in data.split():
data_array.append([])
data_array[-1].append(1)
for j in i:
data_array[-1].append(int(j))
data_array[-1].append(1)
data_array.append([1]*52)
visited = [] # 用来存放已经走过的点
queue = [[(1, 1)]]
start = (1, 1)
end = (30, 50)
visited.append(start)
def bfs(lst, queue, end):
"""
广度优先搜索
:param lst: 数据
:param queue: 队列
:param end: 终点坐标
:return:
"""
if end in queue[-1]:
return queue
alist = []
for now in queue[-1]:
row, col = now
if lst[row+1][col] == 0 and ((row+1, col) not in visited):
alist.append((row+1, col))
visited.append((row+1, col))
if lst[row][col+1] == 0 and ((row, col+1) not in visited):
alist.append((row, col+1))
visited.append((row, col+1))
if lst[row-1][col] == 0 and ((row-1, col) not in visited):
alist.append((row-1, col))
visited.append((row-1, col))
if lst[row][col-1] == 0 and ((row, col-1) not in visited):
alist.append((row, col-1))
visited.append((row, col-1))
queue.append(alist)
return bfs(lst, queue, end)
queue = bfs(data_array, queue, end)
Stack = []
Stack.append(start)
visited_1 = [start]
while Stack[-1] != end:
now = Stack[-1]
row, col = now
i = queue[len((Stack))]
"""由于是D<L<R<U,所以尝试先走D,在走L,其次是R,U"""
if (row+1, col) in i and (row+1, col) not in visited_1:
Stack.append((row+1, col))
visited_1.append((row+1, col))
continue
elif (row, col-1) in i and (row, col-1) not in visited_1:
Stack.append((row, col-1))
visited_1.append((row, col-1))
continue
elif (row, col+1) in i and (row, col+1) not in visited_1:
Stack.append((row, col+1))
visited_1.append((row, col+1))
continue
elif (row-1, col) in i and (row-1, col) not in visited_1:
Stack.append((row-1, col))
visited_1.append((row-1, col))
continue
else:
"""如果走不下去了,就返回"""
Stack.pop()
length_1 = len(Stack)
strstep = ""
for i in range(1,length_1):
if Stack[i][0] > Stack[i-1][0]:
strstep += "D"
elif Stack[i][0] < Stack[i-1][0]:
strstep += "U"
elif Stack[i][1] > Stack[i-1][1]:
strstep += "R"
else:
strstep += "L"
print(strstep)
答案是:
DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR