QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13747|回复: 73

挑战你的智力极限

[复制链接]
发表于 2003-6-19 20:55:38 | 显示全部楼层 |阅读模式
一天鬼谷子出了这道题目:他从2到99中选出两个不同的整数,把积告诉孙膑,把和告诉 庞涓;
庞涓说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。
孙膑说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。
庞涓说:既然你这么说,我现在也知道这两个数字是什么了。

What're the two numbers?
 楼主| 发表于 2003-6-19 20:57:12 | 显示全部楼层
采用分步范围缩小的方法。
1. 两个人刚拿到数字时,没有其他条件,可以确定的是孙数字的范围是 4 - 9801, 是2-99的乘积的范围。庞的数字范围是4-198, 即2-99的和的范围。

2.庞说自己不知道两个数字,孙也一定不知道两个数字。
这说明孙根据乘积不能唯一的分解出两个数,孙就可以从4-9801中去掉所有的唯一分解的数。(好多人说排除两个素数,这是不准确的,例如8=2*4,不是两个素数但是只能唯一的分解,也应该排除)。
而这时庞可以排除的数就更多了,他可以确定孙的数字不是唯一分解数,也就是说:庞的数字分成两个数的和,这两个数的乘积必须还可以按其它方式分解,否则庞不能肯定孙的数的唯一分解性质。例如:庞的数字为6,他觉得原来的数字可以是[2,4], [3,3]. 但是2*4=8, 如果孙有数字8就可以肯定了,既然庞说孙无法肯定,可以排除庞有6的可能。

for M = 4 to 198
for I = 2 to 99
分解M为两个数 I, M-I. 如果M-I不在2-99范围就继续.
计算乘积 I * (M-I) ,如果乘积的分解是唯一就排除M. 否则记录M和乘积的列表。
这一步的结果是:
庞的数可能 孙的相应的可能
11 [18, 24, 28, 30]
17 [30, 42, 52, 60, 66, 70, 72]
23 [42, 60, 76, 90, 102, 112, 120, 126, 130, 132]
27 [50, 72, 92, 110, 126, 140, 152, 162, 170, 176, 180, 182]
29 [54, 78, 100, 120, 138, 154, 168, 180, 190, 198, 204, 208, 210]
35 [66, 96, 124, 150, 174, 196, 216, 234, 250, 264, 276, 286, 294, 300, 304, 306]
37 [70, 102, 132, 160, 186, 210, 232, 252, 270, 286, 300, 312, 322, 330, 336, 340, 342]
41 [78, 114, 148, 180, 210, 238, 264, 288, 310, 330, 348, 364, 378, 390, 400, 408, 414, 418, 420]
47 [90, 132, 172, 210, 246, 280, 312, 342, 370, 396, 420, 442, 462, 480, 496, 510, 522, 532, 540, 546, 550, 552]
53 [102, 150, 196, 240, 282, 322, 360, 396, 430, 462, 492, 520, 546, 570, 592, 612, 630, 646, 660, 672, 682, 690, 696, 700, 702]

3. 孙说它知道了, 所以孙的数字只能出现在上面的其中一行,否则它不能确定。把列表中重复出现的数字去掉, 结果是:
11 [18, 24, 28]
17 [52]
23 [76, 112, 130]
27 [50, 92, 110, 140, 152, 162, 170, 176, 182]
29 [54, 100, 138, 154, 168, 190, 198, 204, 208]
35 [96, 124, 174, 216, 234, 250, 276, 294, 304, 306]
37 [160, 186, 232, 252, 270, 336, 340]
41 [114, 148, 180, 238, 288, 310, 348, 364, 378, 390, 400, 408, 414, 418]
47 [132, 172, 246, 280, 370, 442, 480, 496, 510, 522, 532, 540, 550, 552]
53 [102, 240, 282, 360, 430, 492, 520, 570, 592, 612, 630, 646, 660, 672, 682, 690, 696, 700, 702]

孙取右侧的任何一个数字都可以确定庞的数字,所以能解出结果。

4.庞说它也知道了。庞如果确定孙的数字?除非庞的数字唯一决定孙的数字,上面的数字中
只有 和为17 和 积为52 了。 下面的谁都会解了。

[code:1]
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

bool only(int N) {
int count = 0;
for(int i=2; i< int(sqrt((double)N)) + 1; i++) {
if(i > 99) break;
if(N/i > 99) continue;
if(N/i*i == N) {
count++;
if(count == 2) return false;
}
}
return true;
}

vector<int> only_list;
vector<int> M_set;
vector< vector<int> > N_set;

bool find(vector<int> v, int a) {
vector<int>::iterator it;
for(it = v.begin(); it != v.end(); it++)
if(*it == a) return true;
return false;
}
void show(vector<int> v) {
vector<int>::iterator it;
cout << "[";
for(it = v.begin(); it != v.end(); it++)
cout << *it << " ";
cout << "]";

}

void my_del(vector<int>& a, vector<int>::iterator ia) {
vector<int>::iterator tmp;
for( tmp = ia+1 ; tmp<a.end(); tmp++ ) {
*ia = *tmp;
ia++;
}
a.erase(ia);
}
void remove_between(vector<int>& a, vector<int>& b) {
vector<int>::iterator ia, ib;
for(ia=a.begin(); ia<a.end(); ia++) {
int del = 0;
for(ib=b.begin(); ib<b.end(); ib++)
if(*ia == *ib) {
del = 1;
my_del(b,ib);
}
if(del) my_del(a,ia);
}
}

void remove_same(vector< vector<int> >& v) {
int len = v.size();
for(int i=0; i<len-1; i++)
for(int j=i+1;j<len;j++)
remove_between(v[i],v[j]);
}

int main()
{
for(int i=4;i<=99*99;i++)
if(only(i)) only_list.push_back(i);

vector<int> N_list;
for(int M=4; M<199; M++) {
N_list.clear();
int ok = 1;
for(int i=2; i<100; i++) {
int j = M - i;
if(j>99) continue;
if(j<2) break;
int N = i * j;
if(find(only_list,N)) {
ok = 0;
break;
} else {
if(!find(N_list,N)) N_list.push_back(N);
}
}
if(ok) {
M_set.push_back(M);
N_set.push_back(N_list);
}
}

remove_same(N_set);

for(int i=0; i<M_set.size(); i++) {
cout << M_set[i] << " ";
show(N_set[i]);
cout << endl;
}

cout << "\n";
for(int i=0;i<N_set.size();i++) {
if(N_set[i].size() != 1) continue;
int b = - M_set[i];
int c = N_set[i][0];
cout << "sum: " << -b << ",product: " << c << endl;
int D = int(sqrt((double)b*b-4*c));
int x1 = (-b+D)/2;
int x2 = (-b-D)/2;
cout << "2 numbers are: " << x1 << " , " << x2 << endl;
}


return 0;
}

[/code:1]
回复

使用道具 举报

发表于 2003-6-19 22:14:56 | 显示全部楼层
hehe, the problem is that they use brain, we use computer.

how small we are.
回复

使用道具 举报

发表于 2003-6-20 09:19:00 | 显示全部楼层
brain VS computer
回复

使用道具 举报

发表于 2003-6-20 12:58:38 | 显示全部楼层
我数学不好,分析看不来。
不过,问题中说:
他从2到99中选出两个不同的整数,把积告诉孙膑,把和告诉庞统

但是分析过程中
可以确定的是孙数字的范围是 4 - 9801, 是2-99的乘积的范围。庞的数字范围是4-198, 即2-99的和的范围

应该是6-9702以及5-197
但这不影响分析的结果。
回复

使用道具 举报

发表于 2003-6-20 12:59:49 | 显示全部楼层
下面出一题,如找出答案的,智商起码达到140:
P先生、Q先生都具有足够的推理能力。这天,他们正在接受推理面试。
他们知道桌子的抽屉里有如下16张扑克牌:
红桃   A、Q、4
黑桃   J、8、4、2、7、3
草花   K、Q、5、4、6
方块   A、5
约翰教授从这16张牌中挑出一张牌来,并把这张牌的点数告诉P先生,把这张牌的花色告诉Q先生。这时,约翰教授问P先生和Q先生:你们能从已知的点数或花色中推知这张牌是什么牌吗?
P先生:"我不知道这张牌。" Q先生:"我知道你不知道这张牌。"
P先生:"现在我知道这张牌了。" Q先生:"我也知道了。" 请问:这张牌是什么牌?
回复

使用道具 举报

发表于 2003-6-20 13:03:41 | 显示全部楼层
不是早就问过了么?
刚看了些计算机和数学关系的书
计算机的最高境界是论证数学而不是推理数学或者计算数学啊
回复

使用道具 举报

发表于 2003-6-20 21:01:57 | 显示全部楼层
真是高手
回复

使用道具 举报

发表于 2003-6-22 00:39:29 | 显示全部楼层
是不是真的能编译过
回复

使用道具 举报

发表于 2003-6-22 00:41:22 | 显示全部楼层
vector&lt; vector<int> &gt; N_set;

能过吗?
回复

使用道具 举报

发表于 2003-6-22 16:51:06 | 显示全部楼层
to moonsky:

是不是黑桃4?
回复

使用道具 举报

发表于 2003-6-22 16:54:25 | 显示全部楼层
to atfa:
那个应该是庞涓吧 :)
回复

使用道具 举报

发表于 2003-6-23 09:10:42 | 显示全部楼层
关公战秦琼......
回复

使用道具 举报

发表于 2003-6-23 16:45:12 | 显示全部楼层
我的一个朋友说肯定是方块5
回复

使用道具 举报

发表于 2003-6-23 19:53:49 | 显示全部楼层
[quote:6e6c07a158="ansonlu"]我的一个朋友说肯定是方块5[/quote]

支持
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-7 05:29 , Processed in 0.097501 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表