1-20的两个数把和告诉A,积告诉B,A说不知道是多少,B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少?
1-20的两个数把和告诉A,积告诉B,A说不知道是多少,B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少?
网上流传的题目,说是XX面试题。十有八九是标题党
假设两数不相等。且两人计算能力超强。为了表达方便,重新记一下,A记为甲,B记为乙。两数之和为A,两数之积为B。总共有4步。
1、甲说不知道:
说明A有多种组合。假设A=a+b或A=c+d等。这里不区分a和b,即[2,3]和[3,2]视为同一情况,下同。
易知:A大于等于5,小于等于39。
2、乙也说不知道:
说明B有多种组合。B有多种分解方式,B=a×b或B=e×f等。
3、这时甲说我知道了:
如果正确答案为A=a+b,那么甲是怎么排除掉A=c+d的能?说明甲知道:ab有多种分解方式,cd只有一种分解方式,因为如果答案是c*d,那么乙应该在第二步就得出结论了。(如果A有三种及三种以上组合,那么意味着,除了a+b外,其他组合的积都只有一种分解方式)那么满足这个条件的数有多少组?使用matlab求解。得到和的五种情况。5、6、29、31、32
解释一下:如果和为5,那么可以拆成[1,4]和[2,3]两种情况,如果是第一种[1,4],乘积为4,那么乙在第二步应该就猜出来结果了,所以甲排除[1,4],只能是[2,3],乘积为6,乙不知道是23还是16。举个大一点的例子,如果和是29,可以拆成以下几种情况,易发现,只有当[9,20]这一组才满足条件。因为下面的190、198、204、208、210在20×20这个范围内,只有唯一分解方式。如果是下面这些组合,那么乙在第二步应该猜出来了,所以不是下面五种情况。6个排除5个,就剩一个乘积为180的情况,180可以写成18×10或者9×20。**
满足以上所有条件的所有情况为
即6=2×3或1×6 8=2×4或1×8 180=9×20或10×10 240=15×16或20×12
4、乙接着说我也知道了
根据假设,甲乙两人都有超强计算能力,那么乙应该也知道甲算出来这几种情况。可以看到,最后两种情况的积相同,而乙说他也知道了,所以不可能是最后两种情况。因为如果乙得到的积为240,他是无论如何都无法判断是最后两种的哪一种。
结论:有三组结果:[2,3] [2,4] [9,20]。
现在a、b最大值是20,如果是100的话,可能结果有5组:
做了个小实验,当可取最大范围为5到104,总共100组,统计每组解的个数。好像随着最大值的增加,解的个数也不会变得很多。只做到104,计算越往后越慢。后面太慢了。
最后附上matlab计算代码,参数是取值范围的最大值,即题中的20
// An highlighted block
function result_table2 = shenmeguitimu(max_number)
%% 1-20的两个数把和告诉A,积告诉B,A说不知道是多少,B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少?
%假设两数不相等。假设两人都有超强计算能力。
r_sum=[];
%% 列出所有可能,使用矩阵rssult表示,第一列是a,第二列是b,第三列是和,第四列是积。
All_condition = max_number*max_number-max_number;
result = zeros(All_condition,4);
t = 1;
for a = 1:max_number
for b = 1:max_number
if a ~= b
result(t,1) = a;
result(t,2) = b;
result(t,3) = a + b;
result(t,4) = a*b;
t = t + 1;
end
end
end
%% 从4开始,到最大的数与次大的数之和为止。
sum_ceil = 2*max_number-1;
for sum = 5:sum_ceil
all_pos = find(result(:,3)==sum);%所有满足和为sum的组合位置
size_sum = size(all_pos,1); %和等于sum的组合个数
factorization = 0; %满足多种分解方式的个数。
for i = 1:size_sum %遍历每一组
a = result(all_pos(i),1);
b = result(all_pos(i),2);
product = a*b;
product_pos = find(result(:,4)==product); %找到这个积所有位置
if size(product_pos,1) > 2
factorization = factorization + 1;
end
end
if factorization == 2 %只有一种可能可以多分解,其他都是单分解,所有可能个数减但分解个数等于2
r_sum = [r_sum,sum];
end
end
%% 找出a、b、积
% 应该在上一个循环就找到a、b和积的,想不到怎么组织结构了,再来一遍。
%所有可能结果用result_table表示,形式同result,第一列是a,第二列是b,第三列是和,第四列是积
right_condition = size(r_sum,2);
result_table = zeros(right_condition,4);
for i = 1:right_condition
sum = r_sum(i);
all_pos = find(result(:,3)==sum);%所有满足和为sum的组合位置
size_sum = size(all_pos,1); %和等于sum的组合个数
sum_unit = zeros(1,4);
for j = 1:size_sum %遍历每一组
a = result(all_pos(j),1);
b = result(all_pos(j),2);
product = a*b;
product_pos = find(result(:,4)==product); %找到这个积所有位置
if size(product_pos,1) > 2
sum_unit(1) = a;
sum_unit(2) = b;
sum_unit(3) = sum;
sum_unit(4) = product;
result_table(i,:) = sum_unit;
end
end
end
%% 第四步,去掉表格中积相等的情况。
result_table2 = result_table;
for m = 1:right_condition
product_all = result_table(:,4);
pos_m = find(result_table(m,4)==product_all);
if size(pos_m,1) > 1
result_table2(m,:) = 0;
end
end
result_table2(all(result_table2==0,2),:) = [];
如果哪里错了,请告知一声。我这是从列举和来计算,也可以从列举积来计算。总感觉应该还有更好的方式,希望大家挖掘。第一次写****。希望大家多提意见和建议。