蓝桥杯-九宫重排(python)

蓝桥杯-九宫重排(python)

目录

  • 蓝桥杯-九宫重排(python)
    • 题目描述
    • 思路和总结:

题目描述

  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

蓝桥杯-九宫重排(python)_第1张图片

我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出
输出最少的步数,如果不存在方案,则输出-1。
样例输入

12345678.
123.46758 

样例输出

3

思路和总结:

  刚开始采用dfs,但因为这道题的解空间较深,容易超时,所以换成了bfs。
  刚开始写bfs还是会超时,于是进行改进,将搜索过的结点转化成hash值存储在serached数列中,多通过了一个样例,但还有超时的。
去查找资料找到C语言网-九宫重排题解。
  对比自己代码与其代码的差异之处,发现了以下几点python编程中可以借鉴的地方:

1、一维数组通过坐标转化映射为二维数组,比直接用二维数组更快

2、将搜索过的结点以键值对的方式存在字典当中,因为python的字典实现高效,查看键是否在字典中时不需要遍历所有的键值对。

3、在分类讨论时,可以将不同情况下的变化量提取出来用数组表示,遍历数组来对不同情况写相同的代码,而不是直接向上下左右前进四种情况都分别写一次代码。

4、通过运用divmod获得一维数组表示的二维数组下标

5、交换a、b可以用:a,b=b,a。就省略了中间的temp。

6、[element for row in temp for element in row]

一起来欣赏一下大佬的代码:

def bfs():
    global start, end, cache_state
    stack = [start]
    while stack:
        state = stack.pop(0)
        for direction in around:
            i, j = divmod(state.index('.'), 3)
            if 0 <= i + direction[0] < 3 and 0 <= j + direction[1] < 3:
                # temp = [list(state[3 * k:3 * k + 3]) for k in range(3)]
                # temp[i][j], temp[i + direction[0]][j + direction[1]] = temp[i + direction[0]][j + direction[1]], temp[i][j]
                # temp = ''.join(element for row in temp for element in row)
                temp = list(state)
                idx_0, idx_1 = 3 * i + j, 3 * (i + direction[0]) + j + direction[1]
                temp[idx_0], temp[idx_1] = temp[idx_1], temp[idx_0]
                temp = ''.join(temp)
                if temp not in cache_state:
                    cache_state.setdefault(temp, cache_state[state] + 1)
                    stack.append(temp)
                    if temp == end:
                        return cache_state[end]
 
                         
start, end = [input().strip() for _ in range(2)]
cache_state, around = {start: 0}, [[-1, 0], [0, -1], [1, 0], [0, 1]]
print(bfs())

不好意思地贴一下我自己的代码:




##while True:
s = input()
ls1 = list(s)
s = input()
ls2 = list(s)

queue = list()
# 初始化
i, j = divmod(ls1.index("."), 3)
dot = [i,j]
steps = 0
searched = {"".join(ls1):None}
queue.append([ls1[:], dot[:], steps])
while len(queue)!=0:
    ls1, dot, steps = queue.pop(0)
    if ls1 != ls2 and steps < 81:
        # 向左走
        if dot[1] != 0:
            # 产生结点并加入队列
            ls1[dot[0]*3+dot[1]], ls1[dot[0]*3+dot[1]-1]=ls1[dot[0]*3+dot[1]-1], ls1[dot[0]*3+dot[1]]
            dot[1] -= 1
            temp = "".join(ls1)
            if temp not in searched:
                searched[temp] = None
                queue.append([ls1[:], dot[:], steps+1])
            ls1[dot[0]*3+dot[1]], ls1[dot[0]*3+dot[1]+1]=ls1[dot[0]*3+dot[1]+1], ls1[dot[0]*3+dot[1]]
            dot[1] += 1
        # 向右走
        if dot[1] != 2:
            # 产生结点并加入队列
            ls1[dot[0]*3+dot[1]], ls1[dot[0]*3+dot[1]+1]=ls1[dot[0]*3+dot[1]+1], ls1[dot[0]*3+dot[1]]
            dot[1] += 1
            temp = "".join(ls1)
            if temp not in searched:
                searched[temp] = None
                queue.append([ls1[:], dot[:], steps+1])
            ls1[dot[0]*3+dot[1]], ls1[dot[0]*3+dot[1]-1]=ls1[dot[0]*3+dot[1]-1], ls1[dot[0]*3+dot[1]]
            dot[1] -= 1
        # 向上走
        if dot[0] != 0:
            # 产生结点并加入队列
            ls1[dot[0]*3+dot[1]], ls1[(dot[0]-1)*3+dot[1]]=ls1[(dot[0]-1)*3+dot[1]], ls1[dot[0]*3+dot[1]]
            dot[0] -= 1
            temp = "".join(ls1)
            if temp not in searched:
                searched[temp] = None
                queue.append([ls1[:], dot[:], steps+1])
            ls1[dot[0]*3+dot[1]], ls1[(dot[0]+1)*3+dot[1]]=ls1[(dot[0]+1)*3+dot[1]], ls1[dot[0]*3+ dot[1]]
            dot[0] += 1
        # 向下走
        if dot[0] != 2:
            # 产生结点并加入队列
            ls1[dot[0]*3+dot[1]], ls1[(dot[0]+1)*3+dot[1]]=ls1[(dot[0]+1)*3+dot[1]], ls1[dot[0]*3+dot[1]]
            dot[0] += 1
            temp = "".join(ls1)
            if temp not in searched:
                searched[temp] = None
                queue.append([ls1[:], dot[:], steps+1])
            ls1[dot[0]*3+dot[1]], ls1[(dot[0]-1)*3+dot[1]]=ls1[(dot[0]-1)*3+dot[1]], ls1[dot[0]*3+dot[1]]
            dot[0] -= 1
    else:
        break

if steps == 81:
    print(-1)
else:
    print(steps)

  改进之后的程序在C语言网运行是没问题的,但在蓝桥杯官网却有两个超时,希望有能人志士指点迷津。

参考链接:
C语言网-九宫重排题解

你可能感兴趣的:(蓝桥杯,蓝桥杯,python,深度优先)