Python算法100例-2.8 猜牌术

完整源代码项目地址,关注博主私信'源代码'后可获取

1.问题描述

魔术师利用一副牌中的13张黑桃,预先将它们排好后叠在一起,并使牌面朝下。然后他对观众说:我不看牌,只要数数就可以猜到每张牌是什么,我大声数数,你们听,不信你们就看。魔术师将从最上面的一张牌开始数,第一张把它翻过来正好是黑桃A,他将黑桃A放在桌子上,然后按顺序从上到下数手中的余牌,第二次数1、2,将第一张牌放在这叠牌的下面,将第二张牌翻过来,正好是黑桃2,也将它放在桌子上,第三次数1、2、3,将前面两张依次放在这叠牌的下面,再翻第三张牌正好是黑桃3,这样依次进行,将13张牌全部翻出来,准确无误。问魔术师手中的牌原始次序是怎样安排的?

2.问题分析

先根据题目描述来分析题意。题目中描述的内容比较多,但已经将魔术师出牌的过程描述得很清楚了。

假设桌子上有13个空盒子排成一圈,设定其中一个盒子序号为1,将黑桃A放入1号盒子中,接着从下一个空盒子开始重新计数,当数到第2个空盒子时,将黑桃2放入其中。然后再从下一个空盒子开始重新计数,数到第3个空盒子时,将黑桃3放入其中,这样依次进行下去,直到将13张牌全部放入空盒子中为止。需要注意的是,在计数过程中要跳过那些已放入牌的盒子,而只对空盒子计数。最后牌在盒子中的顺序就是魔术师手中牌的顺序。

3.算法分析

根据问题分析,使用循环结构来实现程序。使用程序将分析过程模拟出来,就可以计算出魔术师手中的牌的原始次序。由于有13张牌,因此显然要循环13次,每次循环时找到与牌序号对应的那个空盒子,因此循环体完成的功能就是找到对应的空盒子将牌存入。

4.确定程序框架

先定义数组a[14]用于存放13张牌,即相当于问题分析中假定的盒子。

定义变量i、j和n,其中i表示牌的序号,j表示数组的下标(盒子的序号),n用来记录当前的空盒序号,初值为1。

程序的主体结构为for循环语句,在for循环中实现将13张牌放入数组a的功能。

1)程序主框架如下:

#外循环13次,每次将一张牌放入空盒中
for i in range(1, 14):                          # i表示牌的序号
    # n用来记录当前的空盒序号,初值为1
    n = 1                                           # 每次都从一个空盒开始重新计数
    while n <= i:
        # 如果盒子非空,继续找下一个盒子
        # 如果盒子为空,判断盒子序号与牌的序号是否相同,相同则存入,不同则继续找

2)将i号牌放入空盒。

该功能使用while循环结构实现,代码如下:

while n <= i:
    if j > 13:
        j = 1
    if a[j]:                                                # 盒子非空,跳过该盒子
        j += 1
    else:
        if n == i:                                          # 判断该盒子是否为第i个空盒
            a[j] = i                                # 是则将i存入
        j += 1
        n += 1

程序流程图如图所示。

在这里插入图片描述

5.完整的程序

根据上面的分析,编写程序如下:

%%time
# 猜牌术

if __name__ == '__main__':
    a = [0] * 14                                            # 初始化列表,用来存放13张牌
    j = 1                                                           # j是数组的下标,空盒子的序号
    print("魔术师手中的牌原始次序是:")
    # 外循环13次,每次将一张牌放入空盒中
    for i in range(1, 14):                          # i表示牌的序号
        # n用来记录当前的空盒序号,初值为1
        n = 1                                               # 每次都从一个空盒开始重新计数
        while n <= i:
            if j > 13:
                j = 1
            if a[j]:                                        # 盒子非空,跳过该盒子
                j += 1
            else:
                if n == i:                                  # 判断该盒子是否为第i个空盒
                    a[j] = i                                # 是则将i存入
                j += 1
                n += 1

    print(a[1:])


魔术师手中的牌原始次序是:
[1, 8, 2, 5, 10, 3, 12, 11, 9, 4, 7, 6, 13]
CPU times: user 0 ns, sys: 249 µs, total: 249 µs
Wall time: 244 µs

6.运行结果

由输出结果可知,魔术师手中的牌的原始次序是1,8,2,5,10,3,12,11,9,4,7,6,13。

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘逸高铁侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值