十二硬币问题

十二硬币问题

==

解题思想源于“约翰·比斯利”(一个歪果仁)
##1、问题重述

给出12个硬币,其中一个是假硬币,用一个天平来确定三种重量的假币(其中假币可能比其他硬币轻或重)。问:至少称量多少次能够保证判断出:是否假币,而且如果有,确定假币是哪一颗,

##2、问题推导

###3颗硬币的情况
我们分析3颗硬币的情况,是为了得出一种分类方法。
三枚硬币测量如图:
第一次称重

第二次称重
经过这两次称重之后,我们可以判断三个信息:

1、是否有假币; 2、假币是哪一颗; 3、假币是轻还是重;

这是三枚硬币的情况,我们称量两次,即可得出上面三个结论。


###9枚硬币的情况
根据三枚硬币的情况,我们将9枚硬币分为三组,
用类似与3枚硬币的方法,两次测量后,我们必然可以得到一下信息(对比三枚硬币情况)

1、是否有假币; 2、假币在哪一组; 3、假币是轻还是重;

如图:
第一次

第二次
接下来我们要干的事情,就是去确定:在已经判断出有假币的组中,确定假币是哪一颗。
3枚硬币,已经知道假币是轻还是重,再通过一次称量,我们就可以确定假币是哪一颗。
如图:
此处输入图片的描述
总结9枚硬币的方法:
9枚硬币,经过3次测量,我们可以获得以下信息:

1、有没有假币; 2、假币是轻是重; 3、假币是哪一颗;


###12枚硬币的情况
在9枚硬币分成3个组的情况下,我们在每个组里加入一枚新硬币,进行第一次称量,如图:
此处输入图片的描述
在此基础上,新加入的硬币不换位置,交换9枚硬币的位置,如图:
此处输入图片的描述
我们可以得到以下信息:

1、硬币是在新加入的3颗中,还是在原来的9颗中(原来的9颗交换了位置,新加入的3颗没有换位置)

基于此,我们进行下面的判断:

如果硬币是在新加入的3颗中,按照3颗硬币的方法,再称量一次就可以找到假币。
如果硬币实在原来的9颗中,按照9颗硬币的方法,再称量一次也可以找到假币。
如果三次都是平衡,判断出没有假币。

如图:
此处输入图片的描述

基于此,我们可以得出结论:

12枚硬币称3次,必定可以找到假币

运用python代码来实现12枚情况的输出:

结果如下:

j ['z', 'z', 'p'] 假币是重的
a ['z', 'p', 'z'] 假币是重的
b ['z', 'p', 'y'] 假币是重的
c ['z', 'p', 'p'] 假币是重的
d ['y', 'z', 'z'] 假币是重的
e ['y', 'z', 'y'] 假币是重的
f ['y', 'z', 'p'] 假币是重的
k ['y', 'y', 'z'] 假币是重的
g ['p', 'y', 'z'] 假币是重的
h ['p', 'y', 'y'] 假币是重的
i ['p', 'y', 'p'] 假币是重的
l ['p', 'p', 'y'] 假币是重的


k ['z', 'z', 'y'] 假币是轻的
e ['z', 'y', 'z'] 假币是轻的
d ['z', 'y', 'y'] 假币是轻的
f ['z', 'y', 'p'] 假币是轻的
j ['y', 'y', 'p'] 假币是轻的
b ['y', 'p', 'z'] 假币是轻的
a ['y', 'p', 'y'] 假币是轻的
c ['y', 'p', 'p'] 假币是轻的
h ['p', 'z', 'z'] 假币是轻的
g ['p', 'z', 'y'] 假币是轻的
i ['p', 'z', 'p'] 假币是轻的
l ['p', 'p', 'z'] 假币是轻的

完毕!


下面是自家原产的python代码

#假设z为左倾,y为右倾,p为平衡,球编号为a~l,situ为情况
#第一次
t1_left="abcj"
t1_right="defk"
t1_undo="ghil"
#第二次
t2_left="defj"
t2_right="ghik"
t2_undo="abcl"
#第三次
t3_left="adgk"
t3_right="behl"
t3_undo="cfij"
#整合
t1=[t1_left,t1_right,t1_undo]
t2=[t2_left,t2_right,t2_undo]
t3=[t3_left,t3_right,t3_undo]#在矩阵中,0为左,1为右,2为平
nb=["z","y","p"]
for i1 in range(3):
    cycle_situ=[]
    situ1=t1[i1]   
    for i2 in range(3):
        situ2=t2[i2]
        for i3 in range(3):
            situ3=t3[i3]
            #判断公共值
            #开始判断
            for zi1 in situ1:
                for zi2 in situ2:
                    if zi1==zi2:
                        for zi3 in situ3:
                        #遍历三个situ中的字符,判断公共值
                            if zi2==zi3:
                                #为输出总的情况准备
                                cycle_situ.append(nb[i1])
                                cycle_situ.append(nb[i2])
                                cycle_situ.append(nb[i3])#把每一次成功找到结果时,天平情况存入矩阵
                                #print(situ1,situ2,situ3)#可查看成功后具体分组情况
                                print(zi3,cycle_situ,"假币是重的")
                                cycle_situ=[]#清空数据
                        
print("\n")#为了让结果输出的时候好看一点
#如果假币为轻,与假币为重不同之处在于,天平右倾,假币在左,天平左倾假币在右,故修改一些假币为重的程序顺序即可
#就只改下面三行
t1=[t1_right,t1_left,t1_undo]
t2=[t2_right,t2_left,t2_undo]
t3=[t3_right,t3_left,t3_undo]#在矩阵中,0为左,1为右,2为平
#完成取轻的一方的操作
nb=["z","y","p"]
all_situ=[]
for i1 in range(3):
    cycle_situ=[]
    situ1=t1[i1]   
    for i2 in range(3):
        situ2=t2[i2]
        for i3 in range(3):
            situ3=t3[i3]
            #判断公共值
            #开始判断
            for zi1 in situ1:
                for zi2 in situ2:
                    if zi1==zi2:
                        for zi3 in situ3:
                        #遍历三个situ中的字符,判断公共值
                            if zi2==zi3:
                                #为输出总的情况准备
                                cycle_situ.append(nb[i1])
                                cycle_situ.append(nb[i2])
                                cycle_situ.append(nb[i3])#把每一次成功找到结果时,天平情况存入矩阵
                                #print(situ1,situ2,situ3)#可查看成功后具体分组情况
                                print(zi3,cycle_situ,"假币是轻的")
                                cycle_situ=[]
###丰丰丰丰丰丰
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值