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。**

1-20的两个数把和告诉A,积告诉B,A说不知道是多少,B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少?

满足以上所有条件的所有情况为
1-20的两个数把和告诉A,积告诉B,A说不知道是多少,B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少?

即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组:
1-20的两个数把和告诉A,积告诉B,A说不知道是多少,B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少?
做了个小实验,当可取最大范围为5到104,总共100组,统计每组解的个数。好像随着最大值的增加,解的个数也不会变得很多。只做到104,计算越往后越慢。后面太慢了。
最后附上matlab计算代码,参数是取值范围的最大值,即题中的20

// An highlighted block
function result_table2 = shenmeguitimu(max_number)
%% 1-20的两个数把和告诉A,积告诉BA说不知道是多少,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),:) = [];

如果哪里错了,请告知一声。我这是从列举和来计算,也可以从列举积来计算。总感觉应该还有更好的方式,希望大家挖掘。第一次写****。希望大家多提意见和建议。