1)我们先一起来看一道简单题:
题目:数学系一共3个班。今天他对我说,你是3班的么?我说,原来你是2班的啊!他说,原来你是1班啊!
只要好好看题了的人就很容易明白题目的意思。只有三个班,他问我是否是3班的,也就是说他一定不是3班的(否则他就不会这么问我了)。而我又知道自己是哪个班的。这样,在排除了3班以及自己所在班级后,就知道他是哪个班的了。而这时候我说了句“原来你是2班的啊”,他用同样方法也可以推出。
其实这道题目的条件有些多余,可以改成这样:
题目:数学系一共3个班。今天他对我说,你是3班的么?我说,我终于知道你是几班的了。他说,我也知道你是几班的了。
同样的分析方法,只有三个班,他问我是否是3班的,也就是说他一定不是3班的(否则他就不会这么问我了)。而我又知道自己是哪个班的。这样,在排除了3班以及自己所在班级后,就知道他是哪个班的了。而我知道了他是哪个班的,并且把这个信息表达了出来(我说“终于知道你是哪个班的了”),也就是说,他也知道了我不是3班的了。他运用这个信息,加上排除法,依然可以分析我是哪个班的。
2)上面那道题只是一个引子,我们来看正题:
一天,鬼谷子随意从2-99中选取了两个数。他把这两个数的和告诉了庞涓, 把这两个数的乘积告诉了孙膑。但孙膑和庞涓彼此不知到对方得到的数。第二天, 庞涓很有自信的
对孙膑说:虽然我不知到这两个数是什麽,但我知道你一定也不知道。随后,孙膑说:
那我知道了。庞涓说:那我也知道了。
我来把这道题的逻辑理一遍。这个工作有点困难,我尽力而为:
1,2~99选出两个不同的数x和y,庞涓知道两个数的和a=x+y,孙膑知道两个数的积b=x*y。他们彼此之间不知道对方的信息。
, 2,庞涓说:“虽然我不知到这两个数是什麽”,这句话的意思是,这两个数之和a一定不是5和297(否则庞涓就会知道这两个数分别是x=2,y=3或x=98,y=99),注意,我们默认x大于y,不影响结果,下同。
3,庞涓又说:“但我知道你一定也不知道”。孙膑掌握着信息b,即两个数的乘积。他根据b无法推出x和y是什么,只能说明,这个数一定是个可拆分数。(可拆分数的定义:可以写成两个数的乘积的方式不止一种,例如18就是一个可拆分数,18=2*9,或18=3*6。
而34就是一个不可拆分数,因为它只能写成:34=2*17,再也无法拆成其他两个数相乘了)
这里还有一个重要的信息,那就是,庞涓知道孙膑一定不知道。注意这个“一定”。也即是说,通过庞涓的信息a可以推出的所有可能的x和y的组合,这些组合的
x和y的乘积b一定(!)都是一个可拆分数。只有当全部的可能的b为可拆分数的时候,庞涓才知道孙膑不可能(!)通过b求出x和y。
4)孙膑说:“那我知道了”。也就是说他综合了前面1)2)3)所有庞涓推测的信息以及自己掌握的信息b后得出来的一个结论。这说明,满足庞涓的信息a=x+y,和孙膑的信息
b=x*y的x和y只可能有一个。(条件4)分析见后)
根据以上几点,我们来求x和y。程序算法是:
第一,a从5循环到197。
第二,x从2循环到a/2,y=a-
第三,p从2循环到根号(b),如果能被b整除,并且p不等于x,。b就是一个可拆分数。如果所有x都满足b是一个可拆分数,那么这些个x所共同对应的一个a就是满足条件3)的一个值。
我用fortran编程,代码如下。No表示这个a不满足条件3),其后的x,y清晰地显示出了他们对应的a的所有xy组合的成绩是个不可拆分数。Yes表示a不满足条件3)。
integer a,b,x,y,p,q,o,i,f
do a=5,197
o=1
do x=2,a/2
y=a-x
b=x*y
do i=1,9999
if(i*)then !求b的开根号,因为我的函数库丢失了,自建了一个函数
f=i-1
exit
endif
enddo
do p=2,f
if(((b-(int(b/p))*p).).and.().and.(p*))then
exit
elseif()then
o=0
endif
enddo
if(.
我通宵解决的史上最难暑假作业鬼谷子孙膑庞涓 来自淘豆网www.taodocs.com转载请标明出处.