第一题:走迷宫

题目: 输入一个二维数组,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))
结果展示
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容

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