猜数字游戏

您所在的位置:网站首页 两个人猜数字 猜数字游戏

猜数字游戏

2024-07-16 04:23| 来源: 网络整理| 查看: 265

使用超过700px宽度的web浏览器查看以获得最佳阅读体验。

从2-80之间(包括2和80)选两个自然数,将他们的积与和分别告诉甲乙两人,假设甲乙两人足够聪明。下面是两人的对话:

乙:甲不论如何也猜不到是哪两个数字。甲:我知道了。乙:我也知道了。

请问是哪两个数字?

逻辑分析

乍一看题面根本没有告诉读者有关这两个数字的任何信息,但是仔细思考就会发现:

从题面来看,甲拿到的是两数之积,乙拿到的是两数之和。由于甲乙两人足够聪明,如果甲拿到的是两素数之积,他一定能够猜到这两个数字。

第一句话展示了乙对甲猜不出这两个数字的绝对自信,这表示乙拿到的和不能被分解为两素数之和,否则甲完全有可能拿到这两个素数的积。

第二句话可以理解为:甲将拿到的数因式分解,并对得到的两个数求和,此时有且仅有一种情况,使得这两个数之和不能被分解为两素数之和,这样便可以唯一确定这两个数。

最后一句话也用同样方式理解:乙将拿到的数进行分解,对每种情况进行第3点中甲的计算,能够满足第3点的分解即为正确的分解情况。

问题详解

以下解答由博主本人构思并撰写,可能不规范,请见谅。

设这两个数分别为 xxx 和 yyy( x,y∈[2,80]x, y \in [2, 80]x,y∈[2,80] ),那么甲拿到的是 xyxyxy,记为 MMM;乙拿到的是 x+yx+yx+y,记为 NNN。

首先,对于 NNN 的所有分解,xxx 和 yyy 不能同时为素数。记 [2,80][2, 80][2,80] 里的素数集合为 S\mathbb{S}S,则

∀(x,y)∈{x+y=N∣x,y∈[2,80]}s.t.(x,y)∉S×S(1) \tag{1} \forall (x, y) \in \{x+y=N \mid x, y \in [2, 80]\} \quad s.t. \quad (x, y) \notin \mathbb{S} \times \mathbb{S} ∀(x,y)∈{x+y=N∣x,y∈[2,80]}s.t.(x,y)∈/S×S(1)

其次,对于满足 (1)(1)(1) 式的 (x∗,y∗)(x^*, y^*)(x∗,y∗),因为 MMM 的限制,又有

∀N∈{x+y∣xy=M∧x,y∈[2,80]∧(x,y)≠(x∗,y∗)}s.t.¬(1)(2) \tag{2} \forall N \in \{x+y \mid xy=M \land x, y \in [2, 80] \land (x, y) \neq (x^*, y^*)\} \quad s.t. \quad \neg (1) ∀N∈{x+y∣xy=M∧x,y∈[2,80]∧(x,y)=(x∗,y∗)}s.t.¬(1)(2)

满足 (2)(2)(2) 式的 (x,y)(x, y)(x,y) 是确定值,即最终的答案。

因此解题步骤应为:枚举 N→N \toN→ 对满足 (1)(1)(1) 式的 (x,y)(x, y)(x,y) 计算 M→M \toM→ 判断是否满足 (2)(2)(2) 式。

如果你是甲,你只需要挑选出和你拿到的 MMM 相等的 (x,y)(x, y)(x,y) 进行计算。

如果你是乙,你不需要枚举 NNN。

接下来采用启发式搜索:

N=4N=4N=4:只有1种分解(2,2)(2, 2)(2,2),排除。N=5N=5N=5:只有1种分解(2,3)(2, 3)(2,3),排除。N=6N=6N=6:有2种分解,其中(3,3)(3, 3)(3,3)是两素数,故排除。N=7N=7N=7:有2种分解,其中(2,5)(2, 5)(2,5)是两素数,故排除。N=8N=8N=8:有3种分解,其中(3,5)(3, 5)(3,5)是两素数,故排除。N=9N=9N=9:有3种分解,其中(2,7)(2, 7)(2,7)是两素数,故排除。N=10N=10N=10:有4种分解,其中(3,7)(3, 7)(3,7)是两素数,故排除。N=11N=11N=11:有4种分解。 (2,9)(2, 9)(2,9):M=18M=18M=18,N′∈{11,9}N' \in \{11, 9\}N′∈{11,9},只有 111111 不能被分解为两素数。满足要求。(3,8)(3, 8)(3,8):M=24M=24M=24,N′∈{11,10}N' \in \{11, 10\}N′∈{11,10},只有 111111 不能被分解为两素数。满足要求。此时满足要求的 (x,y)(x, y)(x,y) 已经多于一个,故排除。N=12N=12N=12:有5种分解,其中(5,7)(5, 7)(5,7)是两素数,故排除。N=13N=13N=13:有5种分解,其中(2,11)(2, 11)(2,11)是两素数,故排除。N=14N=14N=14:有6种分解,其中(7,7)(7, 7)(7,7)是两素数,故排除。N=15N=15N=15:有6种分解,其中(2,13)(2, 13)(2,13)是两素数,故排除。N=16N=16N=16:有7种分解,其中(3,13)(3, 13)(3,13)是两素数,故排除。N=17N=17N=17:有7种分解。 (2,15)(2, 15)(2,15):M=30M=30M=30,N′∈{17,13,11}N' \in \{17, 13, 11\}N′∈{17,13,11},171717 和 111111 都不能被分解为两素数。排除。(3,14)(3, 14)(3,14):M=42M=42M=42,N′∈{17,23,13}N' \in \{17, 23, 13\}N′∈{17,23,13},171717 和 232323 都不能被分解为两素数。排除。(4,13)(4, 13)(4,13):M=52M=52M=52,N′∈{17,28}N' \in \{17, 28\}N′∈{17,28},只有 171717 不能被分解为两素数。满足要求。(5,12)(5, 12)(5,12):M=60M=60M=60,N′∈{17,32,23,19,16}N' \in \{17, 32, 23, 19, 16\}N′∈{17,32,23,19,16},171717 和 232323 都不能被分解为两素数。排除。(6,11)(6, 11)(6,11):M=66M=66M=66,N′∈{17,35,25}N' \in \{17, 35, 25\}N′∈{17,35,25},171717 和 353535 都不能被分解为两素数。排除。(7,10)(7, 10)(7,10):M=70M=70M=70,N′∈{17,37,19}N' \in \{17, 37, 19\}N′∈{17,37,19},171717 和 373737 都不能被分解为两素数。排除。(8,9)(8, 9)(8,9):M=72M=72M=72,N′∈{17,38,27,22}N' \in \{17, 38, 27, 22\}N′∈{17,38,27,22},171717 和 272727 都不能被分解为两素数。排除。满足要求的结果有且仅有 (4,13)(4, 13)(4,13)。

因此结果为 (4,13)(4, 13)(4,13)。

程序验证

靠人力去挨个遍历肯定是行不通的,要想囊括 [2,80][2, 80][2,80] 里的所有情况,就不得不进行程序验证。

于是按照上述的解题步骤,就有了以下的代码:

Python demo# Made by Wanakachi primelist = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157] def divide_n(n): product = [] for i in range(2, n//2+1): # can be divided by 2 prime numbers if i in primelist and n-i in primelist: return [], False # too big if n-i > 80: continue product.append(i*(n-i)) return product, True def divide_m(product): res = [] for m in product: good = [] # from product to sum for i in range(2, int(m**0.5)+1): # too big if i > 80 or m//i > 80: continue if m%i == 0: sum = i+m//i _, no_prime = divide_n(sum) if no_prime: good.append([i, m//i]) # only one sum cannot be divided by 2 prime numbers (where the product comes from) if len(good) == 1: res.append(good[0]) # only one product satisfies the condition -> correct numbers if len(res) == 1: return res[0], True return [], False def main(): for i in range(4, 161): if i == 160: pass product, no_prime = divide_n(i) if not no_prime: continue res, good = divide_m(product) if good: print(res) if __name__ == '__main__': main()

运行这份代码,控制台只会输出 [4,13][4, 13][4,13] 这一对数字,看来这应该就是该范围内唯一的一组解了。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3