文章目录
跳蚱蜢
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
如下图所示: 有 9 只盘子,排成 1 个圆圈。 其中 8 只盘子内装着 8 只蚱蜢,有一个是空盘。 我们把这些蚱蜢顺时针编号为 1 ~ 8。
每只蚱蜢都可以跳到相邻的空盘中, 也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。
请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列, 并且保持空盘的位置不变(也就是 1-8换位,2-7换位,...),至少要经过多少次跳跃?
运行限制
最大运行时间:1s
最大运行内存: 128M
分析
- 一般这种至少,求最小值的问题很适合利用
bfs求解
。 - 首先我们对每个盘子进行编号,由于题目已经编号完毕,那么我们只要设空盘子为0即可。那么我先将这个
圆圈顺时针拉直(拉成直线)
,那么这时候初试状态应该为012345678
,所以依照题意(空盘位置不变,换成逆时针排列),那么这时候最终状态应该为876543210
- 可能有人会说一个圈变成线,某些特性会丧失。但我们这里可以采取一种方法弥补这种丧失特性
(位置变化采取取余的方式)
- 为减少计算量,我们通常会用一个vis列表记录之前存放过的数据,以达到有些重复的状态不计算
(相当于剪枝)
- 而且,我们求解问题的过程应该略微转化,如果考虑的是蚱蜢跳到盘子,如1-0互换,2-0互换…,需要考虑较多种情况,那么我们
只要考虑盘子的变化
即可。
运行代码
from collections import deque
def in_queue(t,dic):
old_pos = t[1] # 之前盘子的位置
new_pos = (old_pos+dic+9)%9 # 避免负数
old_queue = t[0]
# 队列交换过程
new_queue = list(old_queue)
new_queue[old_pos],new_queue[new_pos] = new_queue[new_pos],new_queue[old_pos]
new = "".join(new_queue)
if new not in vis:
q.append((new,new_pos,t[2]+1))
vis.add(new)
q = deque()
q.append(('012345678', 0, 0))# 当前队列,盘子当前位置,变化次数
vis = set() # 去重
vis.add('012345678')
while q:
t = q.popleft() # 经典弹出
if t[0] == '876543210':
print(t[2])
break
in_queue(t,1)
in_queue(t,2)
in_queue(t,-1)
in_queue(t,-2)
通过截图
青蛙跳杯子
题目描述
X 星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X 星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。
*WWWBBB
其中,W 字母表示白色青蛙,B 表示黑色青蛙,∗ 表示空杯子。
X 星的青蛙很有些癖好,它们只做 3 个动作之一:
跳到相邻的空杯子里。
隔着 1 只其它的青蛙(随便什么颜色)跳到空杯子里。
隔着 2 只其它的青蛙(随便什么颜色)跳到空杯子里。
对于上图的局面,只要 1 步,就可跳成下图局面:
WWW*BBB
本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。
输入描述
输入为 2 行,2 个串,表示初始局面和目标局面。我们约定,输入的串的长度不超过 15。
输出描述
输出要求为一个整数,表示至少需要多少步的青蛙跳。
输入输出样例
示例
输入
*WWBB
WWBB*
输出
2
运行限制
最大运行时间:1s
最大运行内存: 256M
分析
- 如果仔细发现的话,应该知道这题与上面那题同一个类型
- 唯一不同的是刚才是环,现在是线性的情况。
- 基本与刚才一致啦,但这里要注意:线性要
判断越界问题
,越界直接减掉即可,以及刚才空杯的位置是固定的,现在这个*位置并不固定,所以还要找到*的位置
。
运行代码
from collections import deque
def in_queue(t,dic):
old_pos = t[1] # 之前空杯的位置
if t[1] + dic < 0 or t[1] + dic >= l:
return
new_pos = t[1]+dic
old_queue = t[0]
# 队列交换过程
new_queue = list(old_queue)
new_queue[old_pos],new_queue[new_pos] = new_queue[new_pos],new_queue[old_pos]
new = "".join(new_queue)
if new not in vis:
q.append((new,new_pos,t[2]+1))
vis.add(new)
s1 = input()
s2 = input()
l = len(s1)
pos = s1.index('*')
q = deque()
q.append((s1, pos, 0))# 当前队列,*当前位置,变化次数
vis = set() # 去重
vis.add(s1)
while q:
t = q.popleft() # 经典弹出
if t[0] == s2:
print(t[2])
break
in_queue(t,1)
in_queue(t,2)
in_queue(t,3)
in_queue(t,-1)
in_queue(t,-2)
in_queue(t,-3)
通过截图
如有错误,敬请指正,欢迎交流,谢谢♪(・ω・)ノ