数学谜题:孙膑与庞涓的数字游戏

数学谜题:孙膑与庞涓的数字游戏

意义深远的题:

孙膑,庞涓都是鬼谷子的徒弟。一天鬼谷子出了这道题目:

他从2到99中选出两个不同的整数,把积告诉孙,把和告诉庞;

庞说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。

孙说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。

庞说:既然你这么说,我现在也知道这两个数字是什么了。

请问这两个数字是什么?为什么?

一开始看这道题真的令人震惊。。。。

还有这种操作的嘛

分析一下吧

选两个数A,B

假定A小于B

判断一下范围

A+B 在[5,197]之间

A * B [6,98*97] 之间

1、庞涓能确定孙膑肯定不知道这两个数

推论1:A与B不能均为质数 why? 这样的话A*B可以做唯一分解,而两个人一开始都是没法直接根据自己手中的数得出结论的

推论2:庞涓的和数一定不能拆成两个质数之和,否则孙膑拿到的积可能拆成唯一一种两个质数之积的情况,此时孙膑就可以猜出这两个数,庞涓不能排除这种可能性,就不会有确信。

根据哥德巴赫猜想,偶数全都不可以成为庞手中的数

歌德巴赫猜想认为任意大于4的偶数都能被拆成两个奇质数之和

推论3:庞涓的和数一定不是大于55的数。因为大于53的数始终能够拆成质数53和另一个大于2的数,在2-99的限制下,这两个数的乘积只有这唯一一种拆分方法。举例:如果庞涓手上的和数是57,可以拆成53+4,当孙膑拿到212这个积,只有453这一种拆分可能性,因为2106的另一种拆分方法导致有一个数超过99。由此排除55以上的所有数

code:

#include

using namespace std;

int prime(int n){

if(n==2) return 1;

int q=sqrt(n);

for(int i=2;i<=q;i++){

if(n%i==0) return 0;

}

return 1;

}

int main(){

int k;

cin>>k;//最大为k 本例为99

k/=2;//取一半

while(!prime(k)){

k++;//找最近的素数

}

for(int i=5;i<=k;i++){

if(i%2==0) continue;//偶数不考虑

int ok=1;

for(int j=2;j<=i/2;j++){//A

if(prime(j)&&prime(i-j)){//可以分解成素数

ok=0;//不ok

break;

}

// printf("sum=%d %d %d\n",i,j,i-j );

}

if(ok){

printf("sum=%d\n",i);

}

}

return 0;

}

2.孙膑知道自己手中的积,并说本来不知道,但现在知道了。

意味着,孙膑看了自己手上的积后,分解因式对应的所有拆分情况中有且仅有一种,两个因数的和是以上11个数中的一个。

举例:当庞涓看到两个数的和是11时,孙膑看到两数的积只能是18(29)、24(38)或者28(47),但不能是30(56)。因为如果是30,可以拆成215、310和56三种情况,其中215和5*6两种情况下,由于2+15=17和5+6=11都在以上11个数内,所以满足庞涓说出第一句话的要求,但孙膑不能确定鬼谷子的两个数是2和15,还是5和6,所以不会说出他已经知道这两个数的话。回头再看积是18的情况,孙膑可以猜到鬼谷子的两个数是2和9或者3和6,但因为3+6=9不在以上11个数内,不满足庞涓说出第一句话的条件,所以不可能,于是只有2和9唯一一种可能。同理,积是24和28的情况都可以类似推理。

code:update!

#include

using namespace std;

int prime(int n){

if(n==2) return 1;

int q=sqrt(n);

for(int i=2;i<=q;i++){

if(n%i==0) return 0;

}

return 1;

}

vector v;

int ans[10050];

int check(int a,int b){

int mul=a*b;

int q=sqrt(mul);

int cnt=0;

for(int i=2;i<=q;i++){

if(mul%i==0){

if(ans[i+mul/i]) cnt++;

}

}

return cnt;

}

int main(){

int k;

cin>>k;//最大为k 本例为99

k/=2;//取一半

while(!prime(k)){

k++;//找最近的素数

}

for(int i=5;i<=k;i++){

if(i%2==0) continue;//偶数不考虑

int ok=1;

for(int j=2;j<=i/2;j++){//A

if(prime(j)&&prime(i-j)){//可以分解成素数

ok=0;//不ok

break;

}

// printf("sum=%d %d %d\n",i,j,i-j );

}

if(ok){

ans[i]++;

v.push_back(i);

printf("sum=%d\n",i);

}

}

for(int i=0;i

int flag=0;

for(int j=2;j<=v[i]/2;j++){

if(check(j,v[i]-j)==1){

flag++;

if(flag==1)printf("%d: ",v[i]);

printf("(%d,%d) ",j,v[i]-j );

}

}

printf("\n");

}

return 0;

}

3、庞涓是知道自己手中的和数,当孙膑猜出两个数后,庞涓也知道了这两个数字,由于庞涓并不知道两数积,所以只能从以上表格出发确定,这就要求第二步有唯一解。

即4,13