甲乙讨论数字
Question:
好像是一道微软的面试题:
已知两个1~30之间的数字,甲知道两数之和,乙知道两数之积。
甲问乙:"你知道是哪两个数吗?"乙说:"不知道";
乙问甲:"你知道是哪两个数吗?"甲说:"也不知道";
于是,乙说:"那我知道了";
随后甲也说:"那我也知道了";
这两个数是什么?
甲问乙:"你知道是哪两个数吗?"乙说:"不知道";
乙问甲:"你知道是哪两个数吗?"甲说:"也不知道";
于是,乙说:"那我知道了";
随后甲也说:"那我也知道了";
这两个数是什么?
思路:
记得好像原来看过类似的一道题,具体答案忘了,只记得当时想的一些思路,但是当时没有仔细去计算最后的结果,突然心血来潮,就想着是否可以编程计算一下,下面是关于这道题的个人想法:
1)甲问乙:"你知道是哪两个数吗?"乙说:"不知道";
设[1-30] * [1-30]的结果存放于集合Mul(共308个数字)中;
乙知道的是两数之积,那么就可以排除掉Mul中在计算[1-30] * [1-30]时只出现一次的数值,得到可能是两数之积的数值(共104个数字,他们都可以一次以上通过1~30内的数字通过乘法运算得到);因为如果乙通过两数之积得到两个数,那么这两个数的相乘结果在进行[1-30] * [1-30]的运算时只会出现一次,但是乙不知道是哪两个数字,所以我们需要排除掉这些只出现一次的数值。
2)乙问甲:"你知道是哪两个数吗?"甲说:"也不知道";
对于Mul中的任一数字Mi,我们都能得到Mi的30以内的多个因子对(<a1,b1>……<an,bn>,其中a1*b1 = an*bn = Mi),对于Mul中所有数字的所有因子对进行加法运算,将得到的结果存放于集合Add(共47个数字)中
甲乙都足够聪明,所以我们乙知道结果只能是在Mul中数字的因子对中,那么只需要对这些因子对进行加法运算即可,同样,因为如果甲通过两数之和得到了最终的两个数,那么这两个数(一个因子对)在进行Mul中数字因子对加法运算时,其结果将只出现一次,所以,需要将只出现一次的加法运算结果排除。
3)于是,乙说:"那我知道了";
设这两个数为x和y,x*y = S,x+y = T,那么我们可以知道,S必然存在于1)之后的Mul中,T必然存在于2)之后的Add中;
乙既然此时说他知道了结果,那么Mul中S的因子对(<a1,b1>…<x,y>…<an,bn>)中只有<x,y>的相加结果会出现在Add中,而其余因子对的结果不在Add中,通过最后的遍历就可以得到结果<x,y>。
4)最后一句,其实已经没有必要了,因为两人足够聪明
最后按照上述步骤编程之后得到的结果为:1 && 4。
vc2005 Code:
https://files.cnblogs.com/zhoueh1991/FindAandB.zip