题目描述
你玩过华容道的游戏吗?
这是个类似的,但更简单的游戏。
看下面 3 x 2 的格子
+---+---+---+
| A | * | * |
+---+---+---+
| B | | * |
+---+---+---+
在其中放 5 张牌,其中 A 代表关羽,B 代表张飞,* 代表士兵。
还有个格子是空着的。
你可以把一张牌移动到相邻的空格中去(对角不算相邻)。
游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。
输入描述
输入两行 6 个字符表示当前的局面
输出描述
一个整数,表示最少多少步,才能把 A B 换位(其它牌位置随意)
样例">样例">样例">样例">样例">样例">样例">样例">样例">输入输出样例
示例
输入
* A
**B
输出
17
这道题很像经典的BFS九宫格移动问题,可以用一维数组转换能二维数组的下标来移动解决
一维变二维下标 :x = index // 数组宽度, y = index % 数组宽度
二维变一维下标 :x * 数组宽度 + y
代码实现
import collections
def bfs(s,A_index,B_index):
q = collections.deque()
dic = {} #使用字典记录每走一步的次数
dic[s] = 0
dist = [(0,1),(0,-1),(1,0),(-1,0)]
q.append(s)
while q:
now = list(q.popleft()) #把字符串转换成逐个添加进列表方便后面操作
if now.index("A") == B_index and now.index("B") == A_index:
return dic["".join(now)] #如果A与B已经交换位置了,直接返回次数
try:
space = now.index(" ")
except:
return 10 #测试样例有个没有空格,题目要求是每组都有移动用的空格的,可能是样例出错了
x,y = space // 3, space % 3 #将一维数组转换成二维数组的索引,并不是实际创建二维数组
distance = dic["".join(now)] #记录当前步数
for i in dist:
tx,ty = i
nx,ny = x + tx, y + ty
if nx in [0,1] and ny in [0,1,2]: #如果没有越界
keynow = now.copy()
keynow[space],keynow[nx*3 + ny] = keynow[nx*3 + ny],keynow[space] #将二维数组的下标转换成一维数组的下标,互换空格与交换点的位置
if "".join(keynow) not in dic.keys(): #如果交换的这个串第一次出现就创建
dic.setdefault("".join(keynow),distance + 1)
q.append(keynow)
return -1
s1,s2 = input(),input()
s = s1+s2
A_index = s.index("A") #A的索引
B_index = s.index("B") #B的索引
print(bfs(s,A_index,B_index))