The 10th Blue Bridge Cup C Language Group A-Maze (bfs double-ended queue)

1. Problem description:

The following figure shows a plan view of a maze, where the obstacles marked 1 are obstacles, and the places marked 0 are passable places.
010000
000100
001001
110000
The entrance of the maze is the upper left corner, and the exit is the lower right corner. In the maze, you can only walk from one position to one of its four directions, up, down, left, and right. For the maze above, starting from the entrance, you can pass through the maze in the order of DRRURRDDDR, a total of 10 steps. Among them, D, U, L, and R indicate go down, up, left, and right respectively. For the following more complicated maze (30 rows and 50 columns), please find a way to go through the maze, which uses the least number of steps. Under the premise of the least number of steps, please find the one with the least lexicographical order as the answer. Please note that D<L<R<U in lexicographic order. (If you copy the following text into a text file, please be sure to check whether the copied content is consistent with the document. There is a file maze.txt in the test question directory with the same content as the text below)

2. Thinking analysis:

This question is a typical search problem. The maze problem can generally be solved by using dfs or bfs. Generally, bfs can find the shortest path from the start point to the end point, while dfs can search for all the paths that can reach the end point. Generally, the shortest path is solved. The problem can be solved by using bfs, because bfs searches for the shortest one and ends the search. The use of bfs to solve generally has the following steps (usually several fixed routines):

a: Declare a queue, add the starting node to the queue, where the node contains the location of the current node, the path contained in the node, and other information

b: Execute the loop when the queue is not empty. The first step is to pop up the first node of the queue (the node that joins the queue first) to determine whether the position meets the position required by the final question, if it is satisfied, then the whole loop is ended, and if it is not satisfied, continue down carried out

c: When the current node that pops up does not meet the final position required by the question, you need to join neighbor nodes that can be reached around this time

Because the python language is used, and the deque is a little more efficient than ordinary queues to pop elements, so the solution is solved with the help of deque collections.deque( ). The elements in the queue are of tuple type, and tuples can be very Conveniently express the location information of the current node and the path to the current node, we can declare a list of records of the current letter path dirs = ["D", "L", "R", "U"], so you can When joining a neighbor node, you can add the corresponding letter through the index

maze.txt:

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

3. The code is as follows:

import collections
if __name__ == '__main__':
    f = open("maze.txt", "r+")
    # 使用readlines()方法读取整个文件, 得到的是一个包含每一行的信息的一维列表
    txt = f.readlines()
    # maze最终会得到二维列表
    maze = list()
    for cur in txt:
        # 使用strip去除每一行的换行符
        maze.append(list(cur.strip("\n")))
    # 使用bfs来搜索从起点到终点的最短路径
    queue = collections.deque()
    queue.append((0, 0, ""))
    pos = [[1, 0], [0, -1], [0, 1], [-1, 0]]
    # 字母对应于上面的pos位置
    dirs = ["D", "L", "R", "U"]
    while queue:
        x, y, path = queue.popleft()
        # print(x, y)
        # 注意是弹出当前的节点之后再判断当前是否到达了最后一个节点
        if x == 29 and y == 49:
            print(path)
            break
        # 遍历上下左右四个方向加入能够到达的位置
        for i in range(4):
            x0, y0 = x + pos[i][0], y + pos[i][1]
            if 0 <= x0 < 30 and 0 <= y0 < 50 and maze[x0][y0] != "1":
                # 在原迷宫上标记已经访问, 或者声明一个二维访问数组
                maze[x0][y0] = "1"
                # 更新可以到达的路径
                queue.append((x0, y0, path + dirs[i]))
    if x != 29 and y != 49: print("No such path!")

 

Guess you like

Origin blog.csdn.net/qq_39445165/article/details/115050748
Recommended