第一题:走迷宫

题目: 输入一个二维数组,1表示不可走,0表示可走,通路是从左上角往右下角找,右下角是出口。要求找到路径最短的走法,且优先级为下左上右,若发现步数一致的走法,则按照字典序对步数结果进行排序。
该迷宫为:
0 1 0 1 0 1 0 1 0 0 1 0 1 1 0 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 0
0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 0 1 0 1
0 1 1 1 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1 1 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 1 1 0 0 1 0 1 1
0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0
1 1 0 0 1 0 0 0 1 1 0 1 0 1 0 0 0 0 1 0 1 0 1 1 0 0 0 1 1 0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 0 1 1 1
0 0 0 1 1 0 1 1 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 0 0
1 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0
0 0 1 1 1 0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 0 1
1 1 0 0 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 1 0 1 0 0 0
0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0 1 0 1 0 1 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 0 1
1 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 1 0 0 0 1 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 1 1
1 0 1 0 1 0 1 0 0 1 1 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 1 1 0 0 1 1 1 1 0 1 1 0 1 0 0 0 0 1 0 0 0
1 0 1 0 1 0 1 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0 0 1 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 1
1 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0
1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 1 1 0 1 0 1 0 0 1
0 0 1 0 1 0 0 1 0 1 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 0 1
1 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 1 0
0 0 0 0 1 0 0 0 1 1 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1
1 0 1 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 0 1
0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 1 0 1
1 0 1 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 0 1 0
0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0
1 1 0 1 0 0 0 0 0 0 1 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 0 0 1 0 1 1 0 1 1 1 0 1 0 0 0
0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1
1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 1 1 0 1 0 0 0
0 0 1 1 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1
1 0 0 0 0 0 0 1 1 0 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 0 0 0 1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 1 0 0 0
我们使用的方法是BFS也就是广度优先搜索。广度优先搜索需要利用队列来解决问题,其思想就是,从某点开始,探索一系列可以走的点,然后再继续从这些点开始,找到更多能走的点,最后达到我们所要完成的目标,点的不重复问题,以及先后顺序问题是非常值得注意的,本题的思想就是从入口出发,然后依次通过BFS找到可以走的点,然后将他们存放到队列中,依次走,去掉重复点,然后通过不断的循环,可以找到最快的路径,也可以利用特定的排序来决定他的走步的先后顺序,非常巧妙,此题应该还有多解,以后更新。实现算法明天手打。

#程序来自CSDN的一个大佬,我只是学习之后自己默写了一遍
#来保存小孩在迷宫中的位置,包含三个元素,一个是横坐标,一个是纵坐标,一个是已经走过的步数以及路线
class Node(object):
    def __init__(self,x,y,w):
        self.x = x
        self.y = y
        self.w = w
    def __str__(self):    
        return self.w
def up(node):
    return Node(node.x-1,node.y,node.w+'U')
def down(node):
    return Node(node.x+1,node.y,node.w+'D')
def left(node):
    return Node(node.x,node.y-1,node.w+'L')
def right(node):
    return Node(node.x,node.y+1,node.w+'R')
#这句if的意思是指只在本文件运行时才会进行执行,__name__在本文件直接执行时,他的值为文件的名称包含后缀,
#而当本文件以import的方式进行引用时,__name__的值为文件的名称不包含后缀,而__main__始终指向文件的名称
#包含后缀。所以达到了直接运行时执行以下的内容,但是作为包import到其他项目中去,if判断为False,所以不
#执行
if __name__ == "__main__":
    #第一步,初步准备
    m,n = map(int,input().split()) #map是python中的内置函数,map(function,iterable),对于每个数据都执行function,返回一个迭代器
    visited = set() #建立一个集合,来存储已经走过的位置,建立集合是因为集合具有不可重复性,在BFS中,有可能发生探索过程中往回走的情况,要通过这种方式进行杜绝             
    queue = [] #建立一个队列,建立队列是因为要进行广度探索,所以要记住每一次走过的点,以及下一次要走的点,这个队列可以对走点的先后顺序进行保证,同时保证广度搜索不会丢点
    #第二步,输入数据
    map_int = [[0]*(n+1)]#因为迷宫是要从1,1为起点的,所以要在上方建立一排0,和左边建立一排0,这样开始的点就可以为1,1了
    #map_int的格式问题:因为我们要做的是二维迷宫,所以我们选择使用二维数组,每一行是一个数组,因为在python中input的类型是str,所以要编入数组还需要进行类型转换
    for i in range(1,m+1):
        map_int.append([0]*(n+1))#加入一行元素,个数与迷宫一行数字的个数相同,达到占位的效果
        nums = input()#输入迷宫数据,按照行输入,不必有空格
        nums = '0' + nums#如之前所说,迷宫要从1,1,开始走,所以左方也要加一排0站位
        for j in range(0,n+1):
            map_int[i][j] = ord(nums[j]) - 48 #ord为python中的内置函数以一个字符为对象,返回他的ASCII码值,本程序使用这种方法将str转换为字符串
    node = Node(1,1,"") #创建第一个节点
    queue.append(node) #将节点放入到队列之中
    #第三步,进行正式的迷宫广度搜索
    while len(queue) != 0:
        movenode = queue[0] #将队列中第一个节点开始移动
        queue.pop(0) #降低一个节点移出队列
        movestr = str(movenode.x)+" "+str(movenode.y)#将节点所移动到的位置记录下来,以防止队列将走过相同的节点
        if movestr not in visited:
            visited.add(movestr) #将节点加入到集合中,然后通过结合来对是否以后节点进行判断,如果已经存在在集合中,则不再加入队列
            #如果满足条件,则对节点进行广度搜索,找到他能走到的符合规则的下一个点     
            if movenode.x ==m and movenode.y ==n:#判断是否已经走到了终点,若走到终点,因为我们只是找最短路径,第一个到终点的一定是步数最少的,所以我们可以直接break
                print(movenode.w)
                break
            #因为题目中要求,同样步数时,按照字典序进行优先级划分,所以我们在进行广度探索时,也按照字典序作为优先级进行遍历,即为D>L>R>U
            if movenode.x<m:#向下
                if map_int[movenode.x+1][movenode.y] ==0:
                    queue.append(down(movenode))
            if movenode.y>1:#向左
                if map_int[movenode.x][movenode.y-1] ==0:
                    queue.append(left(movenode))
            if movenode.y<n:#向右
                if map_int[movenode.x][movenode.y+1] ==0:
                    queue.append(right(movenode))
            if movenode.x>1:#向上
                if map_int[movenode.x-1][movenode.y] ==0:
                    queue.append(up(movenode))
结果展示
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 走格子题目注意点: 以左上角为(0,0)点,类似坐标,使用二维数组去操作。 如果是求最优问题,比如最短路径和背包最...
    Daniel梁阅读 688评论 0 0
  • 目录: Android:Android 0.*Android 1.*Android 2.*Android 3.*A...
    敲代码的令狐葱阅读 4,126评论 0 2
  • 为什么人们大病初愈时,一点都不想吃香的、喝辣的? 可是更搞笑的、更让人哭笑不得的一个事情是:为什么那么多人却可以打...
    章順真阅读 311评论 0 0
  • 今天我们去老妈家串亲戚了 久违的亲切感和热闹的感觉 过年就是热闹才有年味~~ 妈妈做了好多好吃的 爸妈都很贴心,嘿...
    郭玉倩阅读 150评论 0 0
  • 在热情和冷静之间,来回穿梭,周一友人在微信上的一番话,让我觉察到压力,究竟是值得考虑点,无业游民,年龄差距,不...
    米修米修哔哩哔哩阅读 104评论 0 0