一道经典面试逻辑题的python解法

作者: de69a2cfb530 | 来源:发表于2018-07-09 14:32 被阅读4次

    好早之前看到的一个逻辑题:有两个2到99之间的整数,a知道这两个数的和,b知道这两个数的积。

    第一句:a对b说:我不知道这两个数是多少,但我确信你也不知道。

    第二句:b说:我知道了。

    第三句:a说:我也知道了。

    问这两个数是多少? 题不难,只是手动去找没有python写程序找的快,而且用python程序可以在后面进行进一步的探索。

    分析:

    首先是a手上的数是两个数的和,那是在[4,198]之间。

    第一句话分析:a确信b不知道这两个数

    (1)

    比如a手上的数字是8,那么要求的两个数字就有可能是(2,6),(3,5),(4,4)这三种情况,对应的b手上的数字就可能是12,15,16这三种情况,这是来自a的视角。

    但简单分析,第一句话 a确信b不知道这两个数字是多少。那么b手上的数字肯定不可能是15,为什么呢?因为15只有一种分解情况(两个素数相乘):3*5。如果b手上是15,那么b肯定知道这两个数字是3和5了。

    进而可以分析出 a 手上的数字肯定不是8, 因为a手上是8的话,那b手上可能的三种情况(12,15,16) 其中的15这种情况,b是可以分析出这两个数字分别是多少的,而a确信b不知道,所以可以排除8。

    进一步,那a手上什么数字可以排除掉呢?通过上面的分析,

    可以得出 结论(1):a是不能分解成两个素数的和,凡是可以分解成两个素数的和的情况,b是可以知道这两个数的

    上python代码:

    asum1里面存了a手上还可能的数,54个(排除了那些能分解成两个素数的数)

    (2)

    上面的54个可能里面全是奇数,没有偶数。

    进一步分析:a 手上的数字也不能写成(53+2*x,x>=2)这种形式,因为如果可以分解成这种形式,b=53*2*x,因为两个数是小于等于99的,53*2>99了,也只有一种分解情况53,2*x,进而b也知道这两个数字了。

    所以结论(2):比上限/2(99/2=49.5)大的第一个素数(53),+3(56)以后的数字就排除了。

    为什么是+3,因为2*x最小是4.

    所以经过第一句话后,a手上的数字asum2集合 还剩11个

    [11, 17, 23, 27, 29, 35, 37, 41, 47, 51, 53]  <-asum2

    把他们分解了,相乘得到b的粗略集合:

    第二句话分析:b知道了

    b在什么情况下可以说这样的话呢?

    比如b =24, 那么可能的分解(2,12),(3,8),(4,6)两种情况,那么对于的 a就是14,11和10三种情况,这是来自b的视角。

    刚开分析了那么多得出a手上剩下的可能性:[11, 17, 23, 27, 29, 35, 37, 41, 47, 51, 53],这个集合的意思是当a手上是这些数的时候a才敢说第一句话,反言之a手上不是这些数时a就不敢说这些话。

    那么24分解出来得到的 14,11和10三种情况:14,10不在a可能集合里,11在可能集合里。

    11是唯一一个在a可能集合里的,所以b可以分析出a手上的数字是11,因为如果是其他两个数的话,a不敢说第一句话。

    进而得出一个结论:b分解出来的所有两个数eg:(2,12),(3,8),(4,6)所组成的和eg:14,11和10, 有且只有一个存在在a的可能集合里

    经过第二句话b手上可能数字有102个,存入bmul1

    第三句话分析:a知道了

    和第二句话一模一样的分析,a为什么能知道?唯一的可能性就是a手上的数的分解后组成的积有且只有一种情况在集合bmul1里(第二句话算出的集合b)

    现在就只有唯一一个结果了。

    输出结果

    原题到这里就结束了,后面可以展开一些思考。

    (1)既然得出的结论是4和13,不算大,而条件给的是2-99,那么有没有可能把条件范围给小一点,比如给2-20来降低题目难度呢,毕竟这样计算量要小很多。程序里面可以直接把初始条件从99改成20,结果是没有找到符合要求的两个数。为什么呢?

    原因是虽然4和13小于20,但a看到的是17,那么有可能分解成8和9,在a的视角b的数字有可能是72,同时在b的视角的可以分解成2*36,这个36就一下大于20了哦。

    那么把题目换个有趣的问法,同样的对话,两个数字的范围是2-N,N至少取多大,才能保证至少有一个解?

    用程序解很简单,让N从10到99进行一次遍历,看从哪次开始有解了就输出

    得到的结论是:N至少是64才有一个解,(4,13)

    (2) 那么把N扩大,范围扩大,解会变多吗

    如果范围扩大到2-999了,有了第二个解4,61。大家可以思考一下为什么范围在2-99的时候没有出现这个解

    范围扩大到2-9999了,算出来了13个解,分别是:

    1 两个数和: 17 两个数积: 52

    两个数为: [4, 13]

    2 两个数和: 65 两个数积: 244

    两个数为: [4, 61]

    3 两个数和: 89 两个数积: 1168

    两个数为: [16, 73]

    4 两个数和: 127 两个数积: 1776

    两个数为: [16, 111]

    5 两个数和: 137 两个数积: 4672

    两个数为: [64, 73]

    6 两个数和: 163 两个数积: 4192

    两个数为: [32, 131]

    7 两个数和: 179 两个数积: 2608

    两个数为: [16, 163]

    8 两个数和: 185 两个数积: 724

    两个数为: [4, 181]

    9 两个数和: 191 两个数积: 8128

    两个数为: [64, 127]

    10 两个数和: 233 两个数积: 916

    两个数为: [4, 229]

    11 两个数和: 247 两个数积: 1912

    两个数为: [8, 239]

    12 两个数和: 343 两个数积: 9952

    两个数为: [32, 311]

    13 两个数和: 373 两个数积: 19776

    两个数为: [64, 309]

    相关文章

      网友评论

        本文标题:一道经典面试逻辑题的python解法

        本文链接:https://www.haomeiwen.com/subject/wpzauftx.html