2008年7月15日星期二

一道智力题

今天fifi和我哥来家里玩儿了。带她们看了洋葱电影里面Cock Puncher的片断,很HIGH;但是最爽的还是看《超级》英雄了。这两个电影真的是很二也很好看:)

后来,fifi看郁闷了,因为这两个电影确实有些猥琐。她给我出了一道智力题:

已知有两个数m和n,满足2\leq m\leq n \leq 99。A、B两个人分别知道这两个数的合s = m + n与积p = m \times n,但A不知道p的值,B不知道s的值。

然后,两个人就开始变态了:
  1. A说,我不知道m和n是什么数,但我肯定你也不知道。
  2. B说,现在我知道了
  3. A说,现在我也知道了

问m和n的值。

这种题一向让人很头疼。后来我只好写了一个程序搞这个问题。虽然程序风格很烂,还是先帖到这儿,做个纪念……

import collections

kinds = collections.defaultdict(int)

for m in range(2, 100):
for n in range(m, 100):
kinds[m * n] += 1

S = set()
for s in range(4, 198):
isInS = True
for m in range(max(s - 99, 2), min(100, s - 1)):
n = s - m
if n < m:
break
p = m * n
if kinds[p] < 2:
isInS = False
break
if isInS:
S.add(s)

print S

possibleP = collections.defaultdict(int)
for s in S:
for m in range(max(s - 99, 2), min(100, s - 1)):
n = s - m
if n < m:
break
possibleP[m * n] += 1

P = set(p for p, times in possibleP.iteritems() if times == 1)
print P

for s in S:
print s, ":"
for m in range(max(s - 99, 2), min(100, s - 1)):
n = s - m
if n < m:
break
if m * n in P:
print m, n,
print


程序思想很简单。首先,第一句话,其实就是说s是这样一个数:对于\forall m', n',若2\leq m' \leq n'\leq 99, m' + n' = s, m'\cdot n' = p',则p'在2至99中有至少两种分解方法。这样,s的范围就被缩减到一个比较小的集合S中了。

然后就是p了,第二句话的意思实际上是:p跟且仅跟S中的一个s唯一确定一对m, n值。这样p又被缩小到一个比较小的集合P中了。

第三句话,实际上就是说,最后的s仅可能是只与P中的唯一一个p两者能唯一确定一对m, n值的。

分析完这三句话,上面的程序自然就写出来了。分析一下输出结果,应该m, n分别等于4和13。

也不知道对不对。不过,每当编程解了一个题的时候,爽!

2 条评论:

匿名 说...

都太牛了,崇拜

Bighead 说...

经过验证,做得应该是对滴~哈哈~