1~20中选2个数,把这个两个数的和告诉A,2个数的积告诉B。
然后问A知道这两个数是多少吗?A说不知道,再问B知道这两个数是多少吗?B也说不知道。
之后A突然推理出这两个数分别是多少了,并告诉B他知道答案了。
B随后也知道了这两个数是多少了。
请问他们是怎么推理的,这2个数是多少呢?
开头借用了http://blog.csdn.net/u010833547/article/details/53787007的内容。
网上的解答我看过有些,大多都是2,3或者2,4 ;事实上,都漏掉了9,20这个组合。
A,B对话可以分析如下:
1、A说我不知道,解答:形成这个和的组合不止一个!那就先找出都有哪些组合!
2、B说我也不知道,解答:形成这个乘积的组合不止一个!那就先找出都有哪些组合!
同时,将那些组合要么只出现在A中,要么只出现在B中的组合剔除。比如组合对1,4,虽然1,4求和的5可以是1,4、2,3。但是形成的乘积只是是4,组合只有1,4 没有其他的组合,那么1,4组合就要被彻底剔除的。
3、得到剔除后的两个数组,在A形成的数组中,只有一对组合的,就说明,是可选择的结果,但是只有一对组合的有:
[5] => 2,3
[6] => 2,4
[29] => 9,20
[31] => 15,16
[32] => 12,20
这几个组合,但是因为15*16=12*20=240;
所以,如果B手里拿了240这个乘积结果,A手里拿了31或者32他都知道结果,但是B依然不知道组合是15,16和12,20中的哪一个。
所以最后组合应该是:2,3,2,4,9,20。
以下是输出结果:
1、A不知道,那么A拿到的数,形成这样的和的组合不止一个,这是共识,得出以下结果:
Array
(
[5] => 1,4-2,3
[6] => 1,5-2,4
[7] => 1,6-2,5-3,4
[8] => 1,7-2,6-3,5
[9] => 1,8-2,7-3,6-4,5
[10] => 1,9-2,8-3,7-4,6
[11] => 1,10-2,9-3,8-4,7-5,6
[12] => 1,11-2,10-3,9-4,8-5,7
[13] => 1,12-2,11-3,10-4,9-5,8-6,7
[14] => 1,13-2,12-3,11-4,10-5,9-6,8
[15] => 1,14-2,13-3,12-4,11-5,10-6,9-7,8
[16] => 1,15-2,14-3,13-4,12-5,11-6,10-7,9
[17] => 1,16-2,15-3,14-4,13-5,12-6,11-7,10-8,9
[18] => 1,17-2,16-3,15-4,14-5,13-6,12-7,11-8,10
[19] => 1,18-2,17-3,16-4,15-5,14-6,13-7,12-8,11-9,10
[20] => 1,19-2,18-3,17-4,16-5,15-6,14-7,13-8,12-9,11
[21] => 1,20-2,19-3,18-4,17-5,16-6,15-7,14-8,13-9,12-10,11
[22] => 2,20-3,19-4,18-5,17-6,16-7,15-8,14-9,13-10,12
[23] => 3,20-4,19-5,18-6,17-7,16-8,15-9,14-10,13-11,12
[24] => 4,20-5,19-6,18-7,17-8,16-9,15-10,14-11,13
[25] => 5,20-6,19-7,18-8,17-9,16-10,15-11,14-12,13
[26] => 6,20-7,19-8,18-9,17-10,16-11,15-12,14
[27] => 7,20-8,19-9,18-10,17-11,16-12,15-13,14
[28] => 8,20-9,19-10,18-11,17-12,16-13,15
[29] => 9,20-10,19-11,18-12,17-13,16-14,15
[30] => 10,20-11,19-12,18-13,17-14,16
[31] => 11,20-12,19-13,18-14,17-15,16
[32] => 12,20-13,19-14,18-15,17
[33] => 13,20-14,19-15,18-16,17
[34] => 14,20-15,19-16,18
[35] => 15,20-16,19-17,18
[36] => 16,20-17,19
[37] => 17,20-18,19
)
注:左边是和,右边是可能的组合。
2、B也说不知道,可以理解为,要形成B得到数的乘积组合也不止一个,结果如下:
Array
(
[6] => 1,6-2,3
[8] => 1,8-2,4
[10] => 1,10-2,5
[12] => 1,12-2,6-3,4
[14] => 1,14-2,7
[15] => 1,15-3,5
[16] => 1,16-2,8
[18] => 1,18-2,9-3,6
[20] => 1,20-2,10-4,5
[24] => 2,12-3,8-4,6
[28] => 2,14-4,7
[30] => 2,15-3,10-5,6
[32] => 2,16-4,8
[36] => 2,18-3,12-4,9
[40] => 2,20-4,10-5,8
[42] => 3,14-6,7
[45] => 3,15-5,9
[48] => 3,16-4,12-6,8
[54] => 3,18-6,9
[60] => 3,20-4,15-5,12-6,10
[56] => 4,14-7,8
[72] => 4,18-6,12-8,9
[80] => 4,20-5,16-8,10
[70] => 5,14-7,10
[90] => 5,18-6,15-9,10
[84] => 6,14-7,12
[96] => 6,16-8,12
[108] => 6,18-9,12
[120] => 6,20-8,15-10,12
[112] => 7,16-8,14
[126] => 7,18-9,14
[140] => 7,20-10,14
[144] => 8,18-9,16
[160] => 8,20-10,16
[180] => 9,20-10,18-12,15
[240] => 12,20-15,16
)
注:左边是乘积,右边是可能的组合。
3、将所有组合中,要么只出现在求和数组的,要么只出现求积数组的组合找出来,
4、将只出现一次的组合在求和数组和求乘积数组剔除,情况如下;
Array
(
[5] => 2,3(剔除了1,4)
[6] => 2,4
[7] => 1,6-2,5-3,4
[8] => 2,6-3,5
[9] => 1,8-2,7-3,6-4,5
[10] => 2,8-4,6
[11] => 1,10-2,9-3,8-4,7-5,6
[12] => 2,10-4,8
[13] => 1,12-3,10-4,9-5,8-6,7
[14] => 2,12-4,10-5,9-6,8
[15] => 1,14-3,12-6,9-7,8
[16] => 1,15-2,14-4,12-6,10
[17] => 1,16-2,15-3,14-5,12-7,10-8,9
[18] => 2,16-3,15-4,14-6,12-8,10
[19] => 1,18-3,16-4,15-5,14-7,12-9,10
[20] => 2,18-6,14-8,12
[21] => 1,20-3,18-5,16-6,15-9,12
[22] => 2,20-4,18-6,16-8,14-10,12
[23] => 3,20-5,18-7,16-8,15-9,14
[24] => 4,20-6,18-10,14
[25] => 7,18-9,16
[26] => 6,20-8,18-10,16
[27] => 7,20-12,15
[28] => 8,20-10,18
[29] => 9,20
[31] => 15,16
[32] => 12,20
)
剔除只出现一次的组合,形成的求和的数组。也就是A相关的数组。
Array
(
[6] => 1,6-2,3
[8] => 1,8-2,4
[10] => 1,10-2,5
[12] => 1,12-2,6-3,4
[14] => 1,14-2,7
[15] => 1,15-3,5
[16] => 1,16-2,8
[18] => 1,18-2,9-3,6
[20] => 1,20-2,10-4,5
[24] => 2,12-3,8-4,6
[28] => 2,14-4,7
[30] => 2,15-3,10-5,6
[32] => 2,16-4,8
[36] => 2,18-3,12-4,9
[40] => 2,20-4,10-5,8
[42] => 3,14-6,7
[45] => 3,15-5,9
[48] => 3,16-4,12-6,8
[54] => 3,18-6,9
[60] => 3,20-4,15-5,12-6,10
[56] => 4,14-7,8
[72] => 4,18-6,12-8,9
[80] => 4,20-5,16-8,10
[70] => 5,14-7,10
[90] => 5,18-6,15-9,10
[84] => 6,14-7,12
[96] => 6,16-8,12
[108] => 6,18-9,12
[120] => 6,20-8,15-10,12
[112] => 7,16-8,14
[126] => 7,18-9,14
[140] => 7,20-10,14
[144] => 8,18-9,16
[160] => 8,20-10,16
[180] => 9,20-10,18-12,15
[240] => 12,20-15,16
)
剔除只出现一次的组合,形成的求乘积的数组。。也就是B相关的数组。
以下是php源代码:
$sumarray=array();//求和的数组
$jiarray=array();//求乘积的数组
for ($index = 1; $index < 21; $index++) {
for ($index1 = $index+1; $index1 < 21 && $index1>$index; $index1++) {
$sum=$index1+$index;
$sumarray[$index.",".$index1]=$sum;
$jiarray[$index.",".$index1]=$index1*$index;
}
}
$sumarraytemp=array_flip($sumarray);
$jiarraytemp=array_flip($jiarray);
$sumequal=array();//存储同一个和时可能的组合
$jiequal=array();//存储同一个乘积时可能的组合
//求同一个和时可能的组合
foreach ($sumarraytemp as $key => $value) {
foreach ($sumarray as $key1 => $value1) {
if($key==$value1)$sumequal[$key]= isset($sumequal[$key])?$sumequal[$key]."-".$key1:$key1;
}
}
//求同一个乘积时可能的组合
foreach ($jiarraytemp as $key => $value) {
foreach ($jiarray as $key1 => $value1) {
if($key==$value1)$jiequal[$key]= isset($jiequal[$key])?$jiequal[$key]."-".$key1:$key1;
}
}
//同一个和时,只有一种组合的去掉。
foreach ($sumequal as $key => $value) {
if(strpos($value,"-")<1)unset ($sumequal[$key]);
}
//同一个积时,只有一种组合的去掉。
foreach ($jiequal as $key => $value) {
if(strpos($value,"-")<1)unset ($jiequal[$key]);
}
print_r($sumequal);
print_r($jiequal);
$allkey=array();//存储每一种组合出现的次数。要么是1次(要么在求和的组合中一次,要么在求乘积的组合中出现一次),要么2次(同时在求和的组合和求乘积的组合中出现)
foreach ($sumequal as $key => $value) {
if(strpos($value,"-")>0){
$jivaluetemp1="";
$jiarray1= explode("-", $value);
foreach ($jiarray1 as $key1 => $value1) {
if(isset($allkey[$value1]))$allkey[$value1]=2;
else $allkey[$value1]=1;
}
}
else{
if(isset($allkey[$value]))$allkey[$value]=2;
else $allkey[$value]=1;
}
}
foreach ($jiequal as $key => $value) {
if(strpos($value,"-")>0){
$jivaluetemp1="";
$jiarray1= explode("-", $value);
foreach ($jiarray1 as $key1 => $value1) {
if(isset($allkey[$value1]))$allkey[$value1]=2;
else $allkey[$value1]=1;
}
}else{
if(isset($allkey[$value]))$allkey[$value]=2;
else $allkey[$value]=1;
}
}
print_r($allkey);
/**
* 从已经形成的求和组合中和求乘积组合中将只出现一次的组合剔除。
*/
foreach ($sumequal as $key => $value) {
if(strpos($value,"-")>0){
$jivaluetemp1="";
$jiarray1= explode("-", $value);
foreach ($jiarray1 as $key1 => $value1) {
// if($allkey[$value1]<2)unset ($sumequal[$key]);
if($allkey[$value1]<2)unset ($jiarray1[$key1]);
}
if(count($jiarray1)<1){
unset($sumequal[$key]);
continue;
}
$sumequal[$key]= implode("-", $jiarray1);
} else {
if($allkey[$value]<2)unset($sumequal[$key]);
}
}
foreach ($jiequal as $key => $value) {
if(strpos($value,"-")>0){
$jivaluetemp1="";
$jiarray1= explode("-", $value);
foreach ($jiarray1 as $key1 => $value1) {
// if($allkey[$value1]<2)unset ($sumequal[$key]);
if($allkey[$value1]<2)unset ($jiarray1[$key1]);
}
if(count($jiarray1)<1){
unset($jiequal[$key]);
continue;
}
$jiequal[$key]= implode("-", $jiarray1);
} else {
if($allkey[$value]<2)unset($jiequal[$key]);
}
}
print_r($sumequal);
print_r($jiequal);