教授把2-9数种任取2个数,把这两个数的和告诉甲,把这两个数的积告诉乙,
甲说:我不知道
乙说:我也不知道
甲说:我知道了
乙说:我也知道了猜这两个数是?

解决方案 »

  1.   

    因为A不知道,所以老师告诉A的这个数字(和)是一个有多种组合结果。A说不知道,但是A知道B也不知道的时候,A就可以断定数字了,说明这个数字组成的和 和 乘积只有有两个结果。
    2,3被排除了,
    所以我们可以排除只有一种结果的组合和两种以上的组合,和的结果里,和是8以上就有3种以上的结果了,所以只有6,7,如果是6的话,和有 (3|3,2|4),积有(8,9),但是8和9的乘法算法只有一种,2*4,3*3,因为B也说不知道,所以可以排除老师告诉他的乘积不是8,也不是 9,再看看7,和组合(2,5|3,4),积组合(10,12),10只有2*5可得,但是B却说他不知道,而12有可能是3*4,也肯能是2*6,所以 B说也不知道,A听了B说不知道,可以排除2*5,因为10只有是2*5才能得10,所以他应该听到的是7,7只有,3+4,所以他知道了,B听到A说知道了,B就排除了2和6,因为8这个数字有可能是4+4,也有可能是3+5,也有可能是2+6。能算出12的就只有3,4了,所以B说他也知道了。
      

  2.   

    鬼谷子问徒[经典]
    孙膑,庞涓都是鬼谷子的徒弟。一天鬼谷子出了这道题目:
    他从2到99中选出两个不同的整数,把积告诉孙膑,把和告诉庞涓;
    庞涓说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。
    孙膑说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。
    庞涓说:既然你这么说,我现在也知道这两个数字是什么了。
    请问这两个数字是什么?为什么?
    */
    /*
    以下代码,条件1-3分别对应两人依次说的三句话
    算法采用最直接最容易理解的穷举验证法
    *///是否唯一分解(附加条件:分解出的数小于100)
    int isOneSolve(int n, int nMax = 100)
    {
        int nRet=0; //记录满足本条件数
        for (int nd=2; nd*nd<n; ++nd)
        {
            if ( n%nd==0 && n/nd<nMax)
                if (++nRet>1) return 0;
        }
        return nRet;
    }
    //条件1,sum的任意和的分拆之积不可能有唯一分解,否则对方可能猜出
    int p1(int sum)
    {
        if(sum<6) return 0;
        for (int t=(sum-1)/2; t>1; --t)
        {
            if ( isOneSolve(t*(sum-t)) ) return 0;
        }
        return 1;
    }
    //条件2,只有一种积的分拆满足条件1
    int p2(int times2)
    {
        int nRet=0; //记录满足本条件数
        for (int nd=2; nd*nd<times2; ++nd)
        {
            if ( times2%nd==0 && p1(nd+times2/nd) )
                if (++nRet>1) return 0;
        }
        return nRet;
    }
    //条件3,只有一种和的分拆满足条件2
    int p3(int sum)
    {
        int nRet=0; //记录满足本条件数
        for (int t=(sum-1)/2; t>1; --t)
        {
            if ( p2(t*(sum-t)) )
                if (++nRet>1) return 0;
        }
        return nRet;
    }#include <stdio.h>
    //作者:雨中飞燕
    int main(int argc, char *argv[])
    {
        for (int n=6; n<200; ++n) //穷举和的可能,最大不超过200
        {
            // 其和能同时满足条件1和3者即为结果
            if (p1(n) && p3(n))
            {
                //找出对应解
                for (int t=2; t*2<n; ++t)
                {
                    if ( p2(t*(n-t)) ) //分拆结果符合条件2就输出
                        printf("%d %d\n", t, n-t);
                }
            }
        }
        puts("Finish");getchar();return 0;
    }
      

  3.   

    我无语了,写了半天,一刷新全没了.
    好多字啊,不想写了,只写答案的答案6组 223 233 2223
    x=7 y=12 3*4 3+4
    x=8 y=12 2*6 2+6
    x=9 y=18 3*6 3+3
    x=11 y=18 2*9 2+9
    x=11 y=24 3*8 3+8
    x=10 y=24 4*6 4+6 那老师告诉的数组合有这六种情况,然后学生得到的答案也就相应地有六种.
    这里给人的感觉很像二叉树,一个变二个,二个变四个,如果不排除的话,真累死了