0
点赞
收藏
分享

微信扫一扫

跳蚱蜢,青蛙跳杯子(python)

zhaoxj0217 2022-03-24 阅读 29

文章目录

跳蚱蜢

题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

如下图所示: 有 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)

通过截图

在这里插入图片描述

如有错误,敬请指正,欢迎交流,谢谢♪(・ω・)ノ

举报

相关推荐

0 条评论