首页 > 试题广场 >

迷宫问题

[编程题]迷宫问题
  • 热度指数:197118 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

定义一个二维数组 N*M ,如 5 × 5 数组下所示:


int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};


它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。


数据范围: , 输入的内容只包含


输入描述:

输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。



输出描述:

左上角到右下角的最短路径,格式如样例所示。

示例1

输入

5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出

(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)
示例2

输入

5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 1
0 1 1 1 0
0 0 0 0 0

输出

(0,0)
(1,0)
(2,0)
(3,0)
(4,0)
(4,1)
(4,2)
(4,3)
(4,4)

说明

注意:不能斜着走!!     
n,m = map(int,input().split())
matrix = []
for i in range(n):
    s = list(int(x) for x in input().split())
    matrix.append(s)

def dfs(x,y,k):
    if not 0 <= x < n&nbs***bsp;not 0 <= y < m&nbs***bsp;matrix[x][y] == 1&nbs***bsp;(x,y) in k:
        return False 
    if x == n-1 and y == m-1:
        k = k+[(x,y)]
        for i in range(len(k)):
            print('('+str(k[i][0])+","+str(k[i][-1])+')')

    res = dfs(x+1,y,k+[(x,y)])&nbs***bsp;dfs(x-1,y,k+[(x,y)])&nbs***bsp;dfs(x,y+1,k+[(x,y)])&nbs***bsp;dfs(x,y-1,k+[(x,y)])
    return res 

dfs(0,0,[])

编辑于 2022-11-13 15:23:28 回复(0)
'''简单易懂,就是从起始点宽度优先往后探索没有探索过的点,直到终点被探索到'''

class luji:
    def __init__(self, lujin):
        self.lujin=lujin;

def explore(n,l,a,i,j,tt):
    if (i+1<n[0] and a[i+1][j]=='0'):
        a[i+1][j]='1'
        l[i+1][j].lujin=l[i][j].lujin+[[i+1,j]]
        tt.append([i+1,j])
    if (i-1>=0 and a[i-1][j]=='0'):
        a[i-1][j]='1'
        l[i-1][j].lujin=l[i][j].lujin+[[i-1,j]]
        tt.append([i-1,j])
    if (j+1<n[1] and a[i][j+1]=='0'):
        a[i][j+1]='1'
        l[i][j+1].lujin=l[i][j].lujin+[[i,j+1]]
        tt.append([i,j+1])
    if (j-1>=0 and a[i][j-1]=='0'):
        a[i][j-1]='1'
        l[i][j-1].lujin=l[i][j].lujin+[[i,j-1]]
        tt.append([i,j-1])
    
while True:
    try:
        n=input().strip(' ').split(' ')
        n[0]=eval(n[0])
        n[1]=eval(n[1])
        a=[]
        for i in range(n[0]):
            t=input().strip(' ').strip('\r').split(' ')
            a.append(t)
        a[0][0]='1'
        ting=[[0,0]]
        l=[]
        for i in range(n[0]):
            l.append([])
            for j in range(n[1]):
                l[i].append(luji([]))
        l[0][0].lujin=[[0,0]]
        while a[-1][-1]=='0':
            tt=[]
            for i in ting:
                explore(n,l,a,i[0],i[1],tt)
            ting=tt
        for i in l[-1][-1].lujin:
            print("({},{})".format(i[0],i[1]))
    except:
        break

发表于 2021-06-23 23:56:36 回复(0)

因为题目说了,只有一条有效路径,那么我们可以直接使用 dfs 搜索,而可以不用标准的 bfs 来找最短路径。

下面是不带剪枝策略的 dfs 回溯算法,非常直观,直接套用回溯算法模板即可。
代码清晰可读。

import sys


def print_result(path):
    for item in path:
        print('({},{})'.format(item[0], item[1]))


def min_path(maze, visited, path, m, n, i, j):
    if i >= m or j >= n or i < 0 or j < 0:
        return
    if visited[i][j]:
        return 
    if maze[i][j] == 1:
        return
    if i == m-1 and j == n-1 and maze[i][j] == 0:
        path.append((i, j))
        print_result(path)
        return

    path.append((i, j))
    visited[i][j] = True
    min_path(maze, visited, path, m, n, i+1, j)
    min_path(maze, visited, path, m, n, i-1, j) 
    min_path(maze, visited, path, m, n, i, j+1)
    min_path(maze, visited, path, m, n, i, j-1)
    path.pop()
    visited[i][j] = False


def get_input():
    m, n = list(map(int, input().strip().split()))

    maze = []
    for i in range(m):
        row = list(map(int, input().strip().split()))
        maze.append(row)

    return maze, m, n


if __name__ == '__main__':
    try:
        while True:
            maze, m, n = get_input()
            row = [False for _ in range(n)]
            visited = [row.copy() for _ in range(m)]    
            path = []
            min_path(maze, visited, path, m, n, 0, 0)
    except Exception:
        pass
编辑于 2021-05-07 09:16:22 回复(2)
Python,回溯法,可以达到题目要求,但是在跳出递归的时候写的很纠结,希望有大佬帮忙看看如何改进,感谢!!!

def backtracking(n, path, startindex=0):
    """
    :param n: 要搜索的路径点数
    :param startindex: 搜索的起始点
    :return:
    """
    if maze[path[-1][0]][path[-1][1]] == 1:
        return
    if path[-1] == [M-1, N-1]:
        return

    choices = [[0,1],[1,0],[0,-1],[-1,0]]
    for i in range(startindex, n):
        if path[-1] == [M-1, N-1]:
            break
        for j in range(4):
            path.append([path[i][0]+choices[j][0], path[i][1]+choices[j][1]])
            # print(path)
            row, col = path[-1][0], path[-1][1]
            if not (0 <= row < M and 0 <= col < N):
                path.pop()
                continue
            backtracking(n, path, startindex=i+1)
            if path[-1] == [M-1, N-1]:
                break
            path.pop()

while True:
    try:
        M, N = map(int, input().split())
        maze = [list(map(int, input().split())) for i in range(M)]
        path = [[0, 0]]

        backtracking(M+N-2, path)
        for point in path:
            print('('+str(point[0])+','+str(point[1])+')')
    except:
        break


发表于 2021-03-25 16:44:28 回复(0)
代码是很笨的递归,只想说python的递归和c的参数特性有点区别,主要是对于数组的理解上,给我上了一颗,卡了很久,总之注意深浅拷贝,否则出栈后参数不恢复原状态会很麻烦,个人通过自己每一步初始化参数解决了问题,但是肯定是笨蛋做法,希望来个大佬教教我T T
step记录路径
xy为实时坐标
road为当前maza情况
ori用于初始化参数,以便其他子递归不会受到参数变化的影响
由于递归是深度优先,将每种走法记录下来,最后选最短的
import copy
result = []

def trans(step,ori):
    for i in step:
        ori[i[0]][i[1]] = -1
    return ori

def isempty(road,x,y,m,n):
    #一定要先判断越界与否,否则下面的判断会越界从而死掉
    if x == m&nbs***bsp;y == n&nbs***bsp;x == -1&nbs***bsp;y == -1:
        return False
    if road[x][y] == -1&nbs***bsp;road[x][y] == 1:
        return False
    return True

def isend(road,x,y,m,n):
    if x == m-1 and y == n-1:
        return True
    return False

def move(road,x,y,m,n,step,l,ori):
    l += 1
    if isempty(road, x, y, m, n) == False:
        return
    road[x][y] = -1
    
    tmp = [x,y]
    step.append(tmp)
    
    if isend(road, x, y, m, n):
        result.append(step)
        return
    #memory = road 浅拷贝,坑人
    tmp2 = trans(step, copy.deepcopy(ori))
    '''
    for i in tmp2:
        print(i)
    print(step)
    '''
    if isempty(tmp2, x+1, y, m, n):
        move(tmp2, x+1, y, m, n, step, l, ori)
    step = step[:l]
    tmp2 = trans(step, copy.deepcopy(ori))
    if isempty(tmp2, x-1, y, m, n):
        move(tmp2, x-1, y, m, n, step, l, ori)
    step = step[:l]
    tmp2 = trans(step, copy.deepcopy(ori))
    if isempty(tmp2, x, y-1, m, n):
        move(tmp2, x, y-1, m, n, step, l, ori)
    step = step[:l]
    tmp2 = trans(step, copy.deepcopy(ori))
    if isempty(tmp2, x, y+1, m, n):
        move(tmp2, x, y+1, m, n, step, l, ori)

while 1:
    try:
        m,n = map(int, input().split())
        road = []
        for i in range(m):
            road.append(list(map(lambda x:x,map(int,input().split()))))
        result = []
        move(copy.deepcopy(road),0,0,m,n,[],0,copy.deepcopy(road))
        
        point = 0
        lenstep = m*n
        for i in range(len(result)):
            if len(result[i]) < lenstep:
                lenstep = len(result[i])
                point = i

        for i in result[point]:
            print("({},{})".format(i[0], i[1]))
    except:
        break


发表于 2021-03-15 02:29:07 回复(0)

鄙人认为本题出的一般,只有一条路径走得通为什么还要说求最短路径,而且只有一条路径走得通也让大家可以投机取巧,不用广度、深度优先搜索就能出结果(看已通过的代码);

附上本人的广度优先搜索代码:

def bfs(maze,x1,y1,x2,y2):
    directions = [(1,0),(-1,0),(0,1),(0,-1)]
    queue = [(x1,y1,-1)]
    path = []
    while queue:
        path.append(queue.pop(0))
        cur = (path[-1][0],path[-1][1])
        if cur == (x2,y2):
            res = [(path[-1][0],path[-1][1])]
            loc = path[-1][2]
            while loc != -1:
                res.append((path[loc][0],path[loc][1]))
                loc = path[loc][2]
            return res

        for d in directions:
            next_node = (cur[0]+d[0],cur[1]+d[1])
            if 0 <= next_node[0] < len(maze) and \
               0 <= next_node[1] < len(maze[0]) and \
               maze[next_node[0]][next_node[1]] == 0:
                maze[next_node[0]][next_node[1]] == 2
                queue.append((next_node[0],next_node[1],len(path)-1))
while True:
    try:
        m,n = list(map(int, input().split()))
        maze = []
        for i in range(m):
            maze.append(list(map(int, input().split())))
        res = bfs(maze, 0, 0, m-1, n-1)[::-1]
        for i in res:
            print('(%d,%d)'%(i[0],i[1]))
    except:
        break
发表于 2021-02-19 15:18:43 回复(0)
本人写了个精简版的。 用栈实现深度优先搜索,分别存储当前节点和历史路径。注意本题只有唯一解。

while True:
    try:
        st = input().split(' ')
        row = int(st[0])
        column = int(st[1])
        maps = [[] for i in range(row)]
        for i in range(row):
            maps[i] = list(map(int,input().split(' ')))       #构造地图
        res = []
        stack =[(0,0),[]]           #两个元素,分别是当前节点和历史路径。
        while stack:
            path = stack.pop()         #读取历史路径
            node = stack.pop()        #读取当前节点
            path.append(node)       #将当前节点加入路径
            if node ==(row-1,column-1):       #到达终点,保存退出
                res = path
                break
            if node != (row-1,column-1):       #未到达终点,继续搜索
                if node[0] < row-1 and not maps[node[0] + 1][node[1]]:     #注意边界条件!不能越界且下一点不是障碍物
                    stack +=[(node[0]+1,node[1]),path]
                if node[1] < column -1 and not maps[node[0]][node[1] + 1]:     #注意边界条件!不能越界且下一点不是障碍物
                    stack += [(node[0],node[1]+1),path]
        for i in res:
            print(str(i))
    except:
        break 

发表于 2021-02-18 06:53:40 回复(0)
def solve(maze,n,m):
    #标准回溯法解,用yield
    #mark标记走过的点
    mark=[[0 for i in range(m)]  for j in range(n)]
    #path表示当前路径
    path=[]
    #迭代器求解,x,y是下一步的坐标
    def subsolve(x,y):
        #到终点
        if (x,y)==(n-1,m-1):
            path.append((x,y))
            #这里特别重要!
            #一定要深复制!
            yield path[:]
            #注意pop回溯
            path.pop()
        #非法路径
        elif x>=n&nbs***bsp;y>=m&nbs***bsp;x<0&nbs***bsp;y<0 :
            yield []
        elif maze[x][y]==1&nbs***bsp;mark[x][y]==1:
            yield []
        #当前步合法
        else:
            path.append((x,y))
            mark[x][y]=1
            for i,j in ((0,1),(1,0),(-1,0),(0,-1)):
                #遍历迭代器!
                for tem in  subsolve(x+i, y+j):
                    if  tem:
                        #迭代器
                        yield tem
            #弹出
            path.pop()
            mark[x][y]=0

    minpathl = n*m
    minpath = []
    for tem in subsolve(0, 0):
        if len(tem)<minpathl:
            minpathl=len(tem)
            minpath=tem
    return(minpath)

while True:
    try:
        line=input().strip().split()
        n=int(line[0])
        m=int(line[1])
        maze=[]
        for i in range(n):
            line=input().strip().split()
            maze.append([int(i) for i in line])
        ans=solve(maze, n, m)
        for i in ans:
            print('({0},{1})'.format(i[0],i[1]))
    except:
        break
        

发表于 2020-12-30 19:40:34 回复(0)
while True:
    try:
        lines, rows = map(int, input().split())
        matrix = []
        for i in range(lines):
            matrix.append(list(map(int, input().split())))
            
        def find(l, r):
            if (l, r) == (lines-1, rows-1):
                return ["({},{})".format(l, r)]
            if matrix[l][r] == 1:
                return []
            if l<lines-1 and find(l+1, r):
                return ["({},{})".format(l, r)] + find(l+1, r)
            elif r<rows-1 and find(l, r+1):
                return ["({},{})".format(l, r)] + find(l, r+1)
            else:
                return []
            
        root = find(0, 0)
        for p in root:
            print(p)
    except:
        break

发表于 2020-12-16 17:36:31 回复(0)
while True:
    try:
        r,c = map(int,input().split())
        arr = [list(map(int, input().split())) for i in range(r)]

        nl=[]
        vl=[]
        nl.append([(0,(0,0))])
        vl.append((0,0))
        sl=[]
        index=0
        while True:
            l=nl[-1]
            ll=[]
            for i,node in enumerate(l):
                no = node[1]
                if no[0]+1<r and arr[no[0]+1][no[1]] !=1 and (no[0]+1,no[1]) not in vl:
                    ll.append((i,(no[0]+1,no[1])))
                    vl.append((no[0]+1,no[1]))
                if no[1]+1<c and arr[no[0]][no[1]+1] !=1 and (no[0],no[1]+1) not in vl:
                    ll.append((i,(no[0],no[1]+1)))
                    vl.append((no[0],no[1]+1))
                if no[0]-1>=0 and arr[no[0]-1][no[1]] !=1 and (no[0]-1,no[1]) not in vl:
                    ll.append((i,(no[0]-1,no[1])))
                    vl.append((no[0]-1,no[1]))
                if no[1]-1>=0 and arr[no[0]][no[1]-1] !=1 and (no[0],no[1]-1) not in vl:
                    ll.append((i,(no[0],no[1]-1)))
                    vl.append((no[0],no[1]-1))
            nl.append(ll)
            if (r-1,c-1) in vl:
                break
        sl.append((r-1,c-1))
        ln=nl[-1]
        for e in ln:
            if e[1]==(r-1,c-1):
                index=e[0]
        for i in range(2,len(nl)+1):
            tarn=nl[-i]
            tar = tarn[index]
            sl.append(tar[1])
            index=tar[0]
        for e in sl[::-1]:
            print('(' + str(e[0]) + ',' + str(e[1]) + ')')
    except:
        break

发表于 2020-09-10 14:51:00 回复(0)
while 1:
    try:
        a,b = map(int,input().split())
        list0 = []
        for i in range(a):
            list0.append(list(map(int,input().split())))
        res = []
        state = []
        def back(state,changelist,i,j):
            if i == a-1 and j == b-1:
                state += [[i,j]]
                res.append(state)
                return
            if i+1 <= a-1 and changelist[i+1][j] != 1:    #向下走
                changelist_temp = changelist[:]
                changelist_temp[i][j] = 1
                back(state+[[i,j]], changelist_temp, i+1, j)
            if j+1 <= b-1 and changelist[i][j+1] != 1:    #向右走
                changelist_temp = changelist[:]
                changelist_temp[i][j] = 1
                back(state+[[i,j]], changelist_temp, i, j+1)
            if i-1 >= 0 and changelist[i-1][j] != 1:    #向左走
                changelist_temp = changelist[:]
                changelist_temp[i][j] = 1
                back(state+[[i,j]], changelist_temp, i-1, j)
            if j-1 >= 0 and changelist[i][j-1] != 1:    #向上走
                changelist_temp = changelist[:]
                changelist_temp[i][j] = 1
                back(state+[[i,j]], changelist_temp, i, j-1)
        back(state, list0, i=0, j=0)
        res_ = res[0]
        for i in range(len(res_)):
            print('('+str(res_[i][0])+','+str(res_[i][1])+')')
    except:
        break
发表于 2020-08-31 10:37:58 回复(0)
递归的方法,首先将走过的路设为1,避免重复,依次判断 上、下、左、右是否可以走,如果可以,那就递归调用走该条路径。等走到终点时,直接输出路径。(以通过所有测试用例)
import sys
import copy


def get_miniest_path(migong, cur_row, cur_col, cur_path):
    n_row = len(migong)
    n_col = len(migong[0])

    migong[cur_row][cur_col] = 1
    cur_path.append((cur_row, cur_col))
    if cur_row == n_row - 1 and cur_col == n_col - 1:
        return
    # right
    if (cur_col + 1 < n_col and migong[cur_row][cur_col + 1] == 0):
        get_miniest_path(migong, cur_row, cur_col + 1, cur_path)
    # left
    elif (cur_col - 1 >= 0 and migong[cur_row][cur_col - 1] == 0):
        get_miniest_path(migong, cur_row, cur_col - 1, cur_path)
    # down
    elif (cur_row + 1 < n_row and migong[cur_row+1][cur_col] == 0):
        get_miniest_path(migong, cur_row + 1, cur_col, cur_path)
    # up
    elif (cur_row - 1 >= 0 and migong[cur_row-1][cur_col] == 0):
        get_miniest_path(migong, cur_row - 1, cur_col, cur_path)
    else:
        # a dead zone, restore.
        migong[cur_row][cur_col] = 0
        cur_path.pop(-1)


migongs = []
shapes = []
while True:
    try:
        num_row, num_col = tuple(map(int, sys.stdin.readline().strip().split()))
        shapes.append((num_row, num_col))
        for _ in range(num_row):
            migongs.append(list(map(int, sys.stdin.readline().strip().split())))
    except:
        break

start = 0
for (num_row, num_col) in shapes:
    migong = migongs[start: start + num_row]
    start += num_row
    cur_path = []

    get_miniest_path(migong, 0, 0, cur_path)
    for p in cur_path:
        print("({},{})".format(*p))

发表于 2020-08-30 14:35:17 回复(0)
from collections import deque
MAX_VALUE = float('inf')

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

def bfs(maps, begin, end):
    # 用来保存起点到各个位置的最小距离,同时还能用来判断某个点是否被访问过
    dist = [[MAX_VALUE] * m for _ in range(n)]
    # 当前点的上一个点,用于输出路径轨迹
    pre = [[None]*m for _ in range(n)]

    dx = [1, 0, -1, 0]  # 四个方位
    dy = [0, 1, 0, -1]
    # 起点坐标
    startx, starty = begin.x, begin.y
    # 终点坐标
    endx, endy = end.x, end.y

    # 起点到起点的距离初始化为0
    dist[startx][starty] = 0
    queue = deque()
    # 将起点入队列
    queue.append(begin)
    while queue:
        curr = queue.popleft()
        find = False  # 标志位,用于标志是否能够找到一个路径
        # 向四个方向进行试探
        for k in range(4):
            newx, newy = curr.x + dx[k], curr.y + dy[k]
            # 在迷宫内,且当前位置可走,且没有访问过,将其压入队列
            if 0 <= newx < n and 0 <= newy < m and maps[newx][newy] != 1 and dist[newx][newy] == MAX_VALUE:
                dist[newx][newy] = dist[curr.x][curr.y] + 1  # 更新最短距离
                pre[newx][newy] = curr  # 记录前继节点
                # print(pre[newx][newy].x, pre[newx][newy].y)
                queue.append(Point(newx, newy))  # 将该点压入队列中
                # 如果已经到达终点位置
                if newx == endx and newy == endy:
                    find = True
                    break
        if find:
            break

    stack = []
    curr = end

    while True:
        # 先把最后一个点压入栈中
        stack.append(curr)
        if curr.x == begin.x and curr.y == begin.y:
            break
        prev = pre[curr.x][curr.y]

        curr = prev

    while stack:
        curr = stack.pop()
        #print('(%d, %d)' % (curr.x, curr.y))
        print('(' + str(curr.x) + ',' + str(curr.y) + ')')


if __name__ == "__main__":
    # 输入
    n, m = map(int, input().split())
    # maps是地图,visit是访问过的数组
    maps = [[0]*m for _ in range(n)]
    begin = Point()
    end = Point()
    for i in range(n):
        nums = list(map(int, input().split()))
        maps[i] = nums

    # 起点坐标和终点坐标
    begin.x, begin.y = 0,0
    end.x, end.y = n-1, m-1

    bfs(maps, begin, end)
请问我这个在本地打印输出没问题,提交通过是0%,是很么原因?
编辑于 2020-08-14 13:01:52 回复(0)
def dfs(data, i, j, m, n, tmp, res):
    if i > m or j > n or i < 0 or j < 0 or data[i][j] == 1:
        return 0
    tmp.append([i, j])
    if i == m and j == n:
        res.append(tmp)
        return 1

    return dfs(data, i + 1, j, m, n, tmp[:], res) or dfs(data, i, j + 1, m, n, tmp[:], res)

while True:
    try:
        
        m, n = list(map(int, input().split()))
        data = []
        for i in range(m):
            data.append(list(map(int, input().split())))
        tmp = []
        res = []
        dfs(data, 0, 0, m - 1, n - 1, tmp, res)
        for i, j in res[0]:
            print("(%d,%d)" % (i, j))
    except:
        break

编辑于 2020-08-10 10:21:35 回复(0)
deals = [
    lambda x, y: [x + 1, y],  # 向下
    lambda x, y: [x, y + 1],  # 向右
    lambda x, y: [x - 1, y],  # 向上
    lambda x, y: [x, y - 1],  # 向左
]
# 这个顺序有讲究,下右上左可以保证最短路径的节点总是会被优先尝试

def deal_maze(start, end, maze):
    path = [start]  # 走过的路径
    maze[0][0] = 2  # 走过的路径标记为2
    while len(path) > 0:
        cur_node = path[-1]
        if cur_node[0] == end[0] and cur_node[1] == end[1]:
            # 如果当前节点已经到end位置,说明走出了迷宫
            for i in path:
                print("(" + str(i[0]) + "," + str(i[1]) + ")")
        for deal in deals:  # 从上下左右四个方向尝试一遍
            next_node = deal(cur_node[0], cur_node[1])
            if 0 <= next_node[0] <= end[0] and 0 <= next_node[1] <= end[1]:
                # 判断有没有出迷宫
                if maze[next_node[0]][next_node[1]] == 0:  # 坐标为(0,0)的为未走过的通道
                    path.append(next_node)
                    maze[next_node[0]][next_node[1]] = 2  # 走过的路径标记为(2,2)
                    break
        else:
            path.pop()  # 如果for循环正常结束而非break跳出,说明此路不通或者已经找到完整路径了


while True:
    try:
        [a, b] = list(map(int, input().split()))  # a为行,b为列
        input_maze = []  # 迷宫矩阵
        for i in range(a):
            input_maze.append([int(j) for j in input().split()])
        deal_maze([0, 0], (a - 1, b - 1), input_maze)
    except:
        break

这是一段其他作者的代码,在提交的python3答案中排在首位,可惜原创是谁已经无从查证了,非常佩服作者的精妙的思维,因此根据自己的理解添加了一些注释。

发表于 2020-08-02 21:29:31 回复(2)
def path(maze):
    all_path = []
    N,M = len(maze),len(maze[0])
    range_x = list(range(0,N))
    range_y = list(range(0,M))
    def search(route:list,now:tuple):
        if now==(N-1,M-1):
            all_path.append(route)
            return
        x,y = now
        if x+1 in range_x:
            if maze[x+1][y] != 1 and (x+1,y) not in route:
                newroute = route.copy()
                newroute.append((x+1,y))
                search(newroute,(x+1,y))
        if y+1 in range_y:
            if maze[x][y+1] != 1 and (x,y+1) not in route:
                newroute = route.copy()
                newroute.append((x,y+1))
                search(newroute,(x,y+1))
    search([(0,0)],(0,0))
    return all_path
while 1:
    try:       
        M,N = tuple(map(int,input().split()))
        mylist = []
        for i in range(M):
            mylist.append(list(map(int,input().split())))
        Path = path(mylist)
        for i,j in Path[0]:
            print('({0},{1})'.format(i,j))
    except:
        break

可以有多解的

发表于 2020-05-01 09:38:14 回复(0)
dirs = [(0,1),(1,0),(0,-1),(-1,0)]    
def mark(maze,pos):                  
    maze[pos[0]][pos[1]] = 2
def passable(maze,pos):              
    if pos[0]>m-1 or pos[1]>n-1 or pos[0]<0 or pos[1]<0:            
    return maze[pos[0]][pos[1]] == 0
def find_path(maze,pos,end):
    mark(maze,pos)
    if pos == end:                                      
        res.append(pos)                               
        return True                                    
    for i in range(4):                                  
        nextp = pos[0]+dirs[i][0],pos[1]+dirs[i][1]
        if passable(maze,nextp):                        
            if find_path(maze,nextp,end):
                res.append(pos)
                return True
    return False
while True:
    try:
        m, n = input().strip().split()
        m, n = int(m), int(n)
        maze = []
        res=[]
        for i in range(m):
            maze.append(list(map(int, input().strip().split())))
        find_path(maze,pos=(0,0),end=(m-1,n-1))
        for i in range(len(res)-1,-1,-1):
            print('({},{})'.format(res[i][0], res[i][1]))
    except:
        break
递归
编辑于 2020-04-09 14:07:11 回复(0)
我用的Dijkstra算法求得最短路径,本质上是个广度优先搜索
def Dijkstra():
    queue = [] for i in range(raw): for j in range(cow): if G[i][j]!="1":
                queue.append([i, j]) while (len(queue) != 0):
        t=float("inf") for nodes in queue: if t>M[nodes[0]][nodes[1]]:
                t=M[nodes[0]][nodes[1]]
                index_y=nodes[0]
                index_x=nodes[1]
        queue.remove([index_y, index_x]) for i in range(4):
            a = index_y + dy[i]
            b = index_x + dx[i] if a >= 0 and a < raw and b >= 0 and b < cow: if G[a][b] == "0": if M[index_y][index_x] + 1 < M[a][b]:
                        M[a][b] = M[index_y][index_x] + 1  pre[get_vertex_index(a,b)]=get_vertex_index(index_y,index_x)

发表于 2020-02-25 01:28:55 回复(0)
while True:
    try:
        R, C = map(int, input().split())
        mat = [[] for _ in range(R)]
        for i in range(R):
            mat[i] = list(map(int, input().split()))
        res = [[99 for _ in range(C+1)] for _ in range(R+1)]
        res[0][1] = 0
        res[1][0] = 0
        for i in range(1,R+1):
            for j in range(1,C+1):
                if mat[i-1][j-1] == 0:
                    res[i][j] = min(res[i-1][j], res[i][j-1])+1
                    if res[i][j]<99:
                        print('('+str(i-1)+','+str(j-1)+')')
    except:
        break
动态规划,边判断边输出
发表于 2020-02-18 19:26:22 回复(3)

问题信息

难度:
26条回答 100387浏览

热门推荐

通过挑战的用户

查看代码