puzzletwister 发表于 2012-2-27 10:18:08

原帖由 钟七珍 于 2012-2-26 23:37 发表 http://bbs.mf8-china.com/images/common/back.gif

  若是7和22,那么甲被告知的和是29,乙被告知的积是154。和是29,所以甲敢断定乙不知道是哪两个数;乙根据甲的发言,再看手中的积是154,而154可以拆成:7乘22,或2乘77,或14乘11。这三组数的和分别为:29、7 ...
加入和是79,只有分解成2和77,3和76才能保证积小于260,不过这两组积都是不能直接判断出两个数,所以和是79是可以说出第一句话的,89也一样。

nnkken第一步排除的和中少排除了57,因为如果对方的积是4*53还是可以立即判断出两个数的,所以和不能是57,不过似乎对最后结果没有影响

nnkken 发表于 2012-2-27 11:53:21

原帖由 鐘七珍 於 2012-2-26 23:37 發表 http://bbs.mf8-china.com/images/common/back.gif

  若是7和22,那麼甲被告知的和是29,乙被告知的積是154。和是29,所以甲敢斷定乙不知道是哪兩個數;乙根據甲的發言,再看手中的積是154,而154可以拆成:7乘22,或2乘77,或14乘11。這三組數的和分別為:29、7 ...
和是79的話,只有兩種可能性:77+2(積為154)、76+3(積為228),其他可能性均不符合「積小於260」的條件。
所以如果甲手中的和是79的話,他要考慮的是,乙手中的這個積的可能性(154、228)中,是否有任意一個足以讓乙推導出那兩個數。
然而,154=2*77=7*22=11*14
228=3*76=4*57=6*38=12*19
所以,無論乙手中的積是154還是228,乙都不會一開始就知道那兩個數。
所以,如果甲手中的和是79的話,他可以說出「我不知道這兩個數,但我知道乙也不知道這兩個數。」
反過來說,若是7和22,甲手中的和是29而乙手中的積是154的話,由於有和是79的可能性存在,因此乙在第二步不能斷定那兩個數是7和22。

同理,若和是89,則只可能是87+2(積為174)或86+3(積為258)。
174=2*89=3*58=6*29
258=3*86=6*43
甲同樣能斷定乙一開始不知道那兩個數。
因此,若是6和29,由於存在著和是89的可能性,所以乙在第二步不能斷定那兩個數是6和29。

話說這個只是「有點難」的程度嗎……

钟七珍 发表于 2012-2-27 12:21:31

回复 21# 的帖子

  21楼说:“若是7和22,甲手中的和是29而乙手中的積是154的話,由於有和是79的可能性存在,因此乙在第二步不能斷定那兩個數是7和22。”的分析判断是错误的。似乎没有看懂我在17楼的分析解释。
  当乙手中的积是154时,甲手中的和只能是29,而不可能是79(或25)。若和是79(79可以等于32加49,或26加53,或20加59,或18加61,或12加67,或8加71,或6加73之和!而这几组数的积只有唯一的因数分解),甲第一步是不敢说“我知道乙也不知道这两个数”的!所以,乙根据甲的发言,断定甲手中的和只能是29,而不可能是79(或25)。因此乙在第二步就能斷定那兩個數是7和22。

nnkken 发表于 2012-2-27 12:29:39

「79可以等於32加49,或26加53,或20加59,或18加61,或12加67,或8加71,或6加73之和!而這幾組數的積只有唯一的因數分解」
然而這些可能性皆不可能出現,因為:
32*49=1,568
26*53=1,378
20*59=1,180
18*61=1,098
12*67=804
8*71=568
6*73=438
全部都不符合「兩數之積小於260」的條件。
由於這些積不可能是乙手中所得的積,因此甲不需考慮「如果乙手中的積是438,那他就會知道是6和73了」之類的可能性。
因此,正如我在21樓所說,「和是79的話,只有兩種可能性:77+2(積為154)、76+3(積為228),其他可能性均不符合『積小於260』的條件。」

[ 本帖最后由 nnkken 于 2012-2-27 13:47 编辑 ]

钟七珍 发表于 2012-2-27 13:54:32

原帖由 nnkken 于 2012-2-27 12:29 发表 http://bbs.mf8-china.com/images/common/back.gif
「79可以等於32加49,或26加53,或20加59,或18加61,或12加67,或8加71,或6加73之和!而這幾組數的積只有唯一的因數分解」
然而這些可能性皆不可能出現,因為:…………全部都不符合「兩數之積小於260」的條件。
由於這些積不可能是乙手中所得的積,因此甲不需考慮「如果乙手中的積是438,那他就會知道是6和73了」之類的可能性。
  这些数的乘积的确超出了“两数炎积小于260”这个条件。我把自己设置的条件也疏忽了!
  但乙为什么在第四步能猜断定这两个数是7和22呢?

nnkken 发表于 2012-2-27 14:21:25

原帖由 鐘七珍 於 2012-2-27 13:54 發表 http://bbs.mf8-china.com/images/common/back.gif

  這些數的乘積的確超出了「兩數炎積小於260」這個條件。我把自己設置的條件也疏忽了!
  但乙為什麼在第四步能猜斷定這兩個數是7和22呢?
因為積是154的話,和只能是29和79。
而和是79的話,積則可能是154和228。
但乙在第二步說,「我現在依然不知道那兩個數」。
228=76*3=57*4=38*6=19*12
76+3=79
57+4=61
38+6=44
19+12=31
以上四個和之中,只有當和是79時,甲才能在第一步說出「我知道乙肯定不知道」。
(61=2+59、44=3+41、31=2+29,在這三種情況下,乙均可以馬上知道那兩個數)
因此,如果和是79、積是228的話,乙在第二步就已經可以肯定和是79,進而推斷出那兩個數。
但乙沒有在第二步推斷出那兩個數。因此,甲在第三步就可以馬上知道,積不是228而是154,進而推斷出那兩個數是2和77。
但甲沒有在第三步推斷出那兩個數。因此,乙在第四步就可以馬上知道,和不是79而29,進而推斷出那兩個數是7和22。

yq_118 发表于 2012-2-27 22:49:24

我写了个程序算了下,确实有三组解

(4, 43), (6, 29), (7, 22)

#!/usr/bin/python3

START = tuple((i, j)
              for i in range(2, 91)
              for j in range(i, 91)
              if i + j > 11 and i * j < 260)


def mem(f):
    d = {}

    def g(*args):
        if args in d:
            return d
        else:
            d = f(*args)
            return d
    return g


@mem
def A0(sum):
    return tuple(filter(lambda p: p + p == sum, START))


@mem
def B0(product):
    return tuple(filter(lambda p: p * p == product, START))


@mem
def B1(product):
    B = []
    for p in B0(product):
        if known_A_tB(A0(p + p), B0):
            B.append(p)
    return tuple(B)


@mem
def A2(sum):
    A = []
    for p in A0(sum):
        if (known_B_tA(B0(p * p), A0)
            and not known_B(B1(p * p))):
            A.append(p)
    return tuple(A)


@mem
def B3(product):
    B = []
    for p in B1(product):
        if not known_A(A2(p + p)):
            B.append(p)
    return tuple(B)


@mem
def A4(sum):
    A = []
    for p in A2(sum):
        if known_B(B3(p * p)):
            A.append(p)
    return tuple(A)


def known_A(A):
    return len(A) == 1


def known_B(B):
    return len(B) == 1


def known_A_tB(A, Bn):
    for p in A:
        if known_B(Bn(p * p)):
            return False
    return True


def known_B_A(B, An):
    for p in B:
        if not known_A(An(p + p)):
            return False
    return True


def known_B_tA(B, An):
    for p in B:
        if known_A(An(p + p)):
            return False
    return True


def test(x, y):
    A = A0(x + y)
    if known_A(A) or not known_A_tB(A, B0):
        return False

    B = B0(x * y)
    if known_B(B) or not known_B_tA(B, A0):
        return False

    B = B1(x * y)
    if known_B(B):
        return False

    if known_B_A(B, A2) or known_B_tA(B, A2):
        return False

    A = A2(x + y)
    if known_A(A):
        return False

    B = B3(x * y)
    if not known_B(B):
        return False

    A = A4(x + y)
    if not known_A(A):
        return False

    return True


if __name__ == '__main__':
    a = []
    for p in START:
        if test(p, p):
            a.append(p)
    print(a)

nnkken 发表于 2012-2-27 22:58:36

……樓上強大……
我只懂用程序輔助列出某些情況的可能性列表……

钟七珍 发表于 2012-2-28 11:52:34

  谢谢27楼的编程分析!谢谢nnkken参与此帖的多次讨论!
  转了四步分析法的帖子之后,考虑能否扩展为五步分析呢?思考的结果原:题条件不变,只是多一步分析,仍然只有唯一的一组解(已知两个数的和与积,五步分析:
  有两个在2到99间的整数,告诉甲这两个数的和,告诉乙这两个数的积。由甲乙轮流发言,请甲先说。
  第一步,甲:我不知道这两个数,但我知道乙也不知道这两个数。
  第二步,乙:一开始我不知道之两个数,但知道甲也不知道这两个数:现在我仍然不知道是哪两个数。(乙还有一句话:“无法判断甲现在是否知道是哪两个数”没有说出来。)
  第三步,甲:我仍然不知道是哪两个数。
  第四步,乙:哈哈!我知道是哪两个数了!
  第五步,甲:哈哈,我也知道这两个数了!
  请问:这是哪两个数?)。
  后来想把难度加大,故设置了两个限制条件:“同时告知甲乙双方:两个数的和大于11、两数的积小于260”。但考虑不周,“两数的积小于260”这个条件反而带来多解(只设前一个条件,不设后一个条件,则此题无解)。
  好在多解有限,按17楼算法只有三解,勉强可仍作一题。

yq_118 发表于 2012-2-28 20:47:52

如果把“两数的积小于260”里的260改成360就只有唯一解(16,19)了
页: 1 2 [3] 4
查看完整版本: 已知两个数的和与积,五步分析,难度较大