一个老师从2到9中取两个数字,给甲说了积,给已说了和,甲说我不知道,已说我也不知道,甲又说我知道,已又说我知道,这两个数分别是多少,求大神解

解决方案 »

  1.   

    答案是3和8
    推理过程:
    既然甲一开始说不知道,说明至少有两种可能,满足这样条件的乘积只可能是3个:
    12, 18, 24
    先看12,可能是2 X 6,也可能是 3 X 4.若 2 X 6,则乙得 8,对于乙来说,只有两种可能: 2 + 6 =8, 3 + 5 = 8,但3 X 5 = 15, 15对于甲来说只有一种可能,但甲说不知道,所以只可能是2和6,但乙却说不知道,可见不是12.
    再看24,可能是4 X 6,也可能是3 X 8.若4和6,则乙得10,有两种可能: 4 + 6 = 10, 2 + 8 = 10, 对乙来说,2和8不可能,因为2 X 8 = 16只有一种可能。
    若是3 X 8,则乙得11,两种可能: 2 + 9 = 11,3 + 8 = 11。 2 X 9 = 18对甲来说也有两种可能。所以乙一开始说不知道,而甲一听乙说不知道,就排除了4 X 6,故得3,8, 而乙也排除了2 + 9,同样得3,8。如何编程,容老夫再想想 
      

  2.   

    好像上面说错了。怎么这个问题感觉无解?
    首先,楼上说的3和4肯定是错的:
    这时乙得7, 则 2 + 5, 3 + 4,但2 x 5只有一种可能,所以乙一开始就能推出是3和4。但乙说不知道,故矛盾。现在假设乙得了11,则2 + 9, 3 + 8,其他如4 + 7, 5 + 6对甲来说都只有一种可能,可排除。
    2 + 9,甲得18,则 2 x 9, 3 x 6,甲推理:若3 x 6, 则乙得 9, 3 + 6, 2 + 7, 2 + 7一种可能,所以乙可推得3和6,但乙说不知道,则2和9。但是问题在于,当甲说知道了之后,乙不好推理,仍然无法知道是2和9还是3和8。因为若3和8,甲得24,3 x 8, 4 x 6,甲推理:若4 x 6,乙得10, 2 + 8(对甲来说16,一种可能),3 + 7(对甲来说21),4 + 6,所以乙可推得必为4 + 6,但乙说不知道,所以只能是3和8,乙得11,无法确定。也就是说,当甲回答说知道后,乙仍然无法确定是2和9还是3和8!所以乙怎么可能说知道呢?如果谁能证明我说错了,不胜感激!
      

  3.   

    VFP代码:
    Create Cursor tt (ti n(1),tj n(1),ixj n(2),ipj n(2))
    For i= 2 To 9
    For j=2 To 9
    If i=j
    Loop
    Endif 
    locate for ti=j And tj=i
    If Found()
    Loop
    Endif 
    Insert Into tt Values (i,j,i*j,i+j)
    Endfor 
    EndforSelect ixj,Count(ixj) as xn From tt Into Cursor t1 Group By ixj Having xn=1
    Select t1
    Scan
    Select tt
    Delete For ixj=t1.ixj
    Select t1
    EndscanSelect ipj,Count(ipj) as xn From tt Into Cursor t1 Group By ipj Having xn=1
    Select t1
    Scan
    Select tt
    Delete For ipj=t1.ipj
    Select t1
    Endscan
    Use In t1
    Select tt
    Browse 结果有两条记录2/9,3/8,命题为假。9楼正确
      

  4.   

    写个程序算一下:using System;
    using System.Linq;namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var 老师可能出的题 = from a in Enumerable.Range(2, 8)
                         from b in Enumerable.Range(2, 8)
                         where a < b
                         select new { A = a, B = b, 积 = a * b, 和 = a + b };
                var 甲说不知道时 = from u in 老师可能出的题
                             group u by u.积 into g
                             where g.Count() > 1
                             select g.First();
                var 乙说不知道时 = from u in 老师可能出的题
                             group u by u.和 into g
                             where g.Count() > 1
                             select g.First();
                var 甲说知道了时 = from u in 甲说不知道时
                             join v in 乙说不知道时 on u.积 equals v.积
                             group u by u.积 into g
                             where g.Count() == 1
                             select g.First();
                var 乙说知道了时 = from u in 乙说不知道时
                             join v in 甲说知道了时 on u.和 equals v.和
                             group u by u.和 into g
                             where g.Count() == 1
                             select g.First();
                foreach (var result in 乙说知道了时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                Console.ReadKey();
            }
        }
    }
      

  5.   

    呵呵,修改一下using System;
    using System.Linq;namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var 老师可能出的题 = from a in Enumerable.Range(2, 8)
                         from b in Enumerable.Range(2, 8)
                         where a < b
                         select new { A = a, B = b, 积 = a * b, 和 = a + b };
                var 甲说不知道时 = from u in 老师可能出的题
                             group u by u.积 into g
                             where g.Count() > 1
                             select g.First();
                var 乙说不知道时 = from u in 甲说不知道时
                             group u by u.和 into g
                             where g.Count() > 1
                             select g.First();
                var 甲说知道了时 = from u in 甲说不知道时
                             join v in 乙说不知道时 on u.积 equals v.积
                             group u by u.积 into g
                             where g.Count() == 1
                             select g.First();
                var 乙说知道了时 = from u in 乙说不知道时
                             join v in 甲说知道了时 on u.和 equals v.和
                             group u by u.和 into g
                             where g.Count() == 1
                             select g.First();
                foreach (var result in 乙说知道了时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                Console.ReadKey();
            }
        }
    }
    看看,修改了哪里?
      

  6.   

    那么再改一下好了!using System;
    using System.Linq;namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var 老师可能出的题 = from a in Enumerable.Range(2, 8)
                              from b in Enumerable.Range(2, 8)
                              where a < b
                              select new { A = a, B = b, 积 = a * b, 和 = a + b };
                var 甲说不知道时 = from u in 老师可能出的题
                             group u by u.积 into g
                             where g.Count() > 1
                             select g.First();
                var 乙说不知道时 = from u in 甲说不知道时
                             group u by u.和 into g
                             where g.Count() > 1
                             select g.First();
                var 甲说知道了时 = from u in 乙说不知道时
                             group u by u.积 into g
                             where g.Count() == 1
                             select g.First();
                var 乙说知道了时 = from u in 甲说知道了时
                             group u by u.和 into g
                             where g.Count() == 1
                             select g.First();
                foreach (var result in 乙说知道了时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                Console.ReadKey();
            }
        }
    }
      

  7.   

    嗯,还可以修改一行   from b in Enumerable.Range(a + 1, 9 - a)
    不改了!
    实际上这不是什么专门设计的算法,这是笨拙的遍历。只不过,Linq具有迭代器功能(linq的所谓“延迟计算”能力就是基于迭代器机制的),因此我们可以写出看似笨拙的遍历方法,然后让Linq编译器去给我们转换成为比较高效的迭代计算过程。在迭代过程中Linq所占用的内存很小,这是其优势。
      

  8.   


    牛~~~DDDDD   命题都没看明白的人伤不起啊~~~
      

  9.   

    有点问题啊,这个算法
     var 甲说不知道时 = from u in 老师可能出的题
                             group u by u.积 into g
                             where g.Count() > 1
                             select g.First();
    见上面这里按照 积 进行了一下group by操作, where条件 中 g.Count() > 1 
    所以 按照积分组了一下 针对相同积 情况下 只检索了 一个记录 丢失部分数据
    可见结果不会正确的
    针对积相同的数据
      

  10.   

    此推理正解
    sp1234的程序明显BUG
      

  11.   


    不懂这句是什么意思。你可以在这句之后打印一下foreach (var result in 甲说不知道时)
        Console.WriteLine("A={0}, B={1}", result.A, result.B);
    看看跟你想的结果是否一致!
      

  12.   


    恩,确实 g.First是有BUG的。我后边修改一下!
      

  13.   

     var 甲说不知道时 =from u in 老师可能出的题
                             group u by u.积 into g
                             where g.Count() > 1
                             select g.First();            foreach (var result in 甲说不知道时)
                    Console.WriteLine("A={0}, B={1},A*B={2}", result.A, result.B, result.积);结果如下:
    A=2, B=6,A*B=12
    A=2, B=9,A*B=18
    A=3, B=8,A*B=24
    明显漏掉了  A=3, B=4, A*B=12 
              ... ...
               A=4, B=6, A*B=24 等类似情况
    很抱歉上面没有说明白,举例你能明白吧... ...
      

  14.   

    啤酒,酒鬼鱼.....坐等sp1234使用linq取重复数据代码... ...呵呵 
      

  15.   

    在2-9这八个数的和,积中,
    和有重复的&&积有重复的&&重复的和的个数是2&&重复的积的个数也是2
    满足这个条件的只有2,6和3,4这两组数
      

  16.   

    恩,前边两个的g.First删除了,在增加代码打印了一下过程。using System;
    using System.Linq;namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var 老师可能出的题 = from a in Enumerable.Range(2, 8)
                              from b in Enumerable.Range(a + 1, 9 - a)
                              where a < b
                              select new { A = a, B = b, 积 = a * b, 和 = a + b };
                var 甲说不知道时 = from u in 老师可能出的题
                             where 老师可能出的题.Any(x => x.A != u.A && x.积 == u.积)
                             select u;
                Console.WriteLine("----------甲说不知道时");
                foreach (var result in 甲说不知道时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                var 乙说不知道时 = from u in 甲说不知道时
                             where 甲说不知道时.Any(x => x.A  != u.A  && x.和 == u.和)
                             select u;
                Console.WriteLine("----------乙说不知道时");
                foreach (var result in 乙说不知道时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                var 甲说知道了时 = from u in 乙说不知道时
                             group u by u.积 into g
                             where g.Count() == 1
                             select g.First();
                Console.WriteLine("----------甲说知道了时");
                foreach (var result in 甲说知道了时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                var 乙说知道了时 = from u in 甲说知道了时
                             group u by u.和 into g
                             where g.Count() == 1
                             select g.First();
                Console.WriteLine("----------乙说知道了时");
                foreach (var result in 乙说知道了时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                Console.ReadKey();
            }
        }
    }
      

  17.   

    其实假设“老师从1到9中取两个数字”,这个题目就有解了。using System;
    using System.Linq;namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var 老师可能出的题 = from a in Enumerable.Range(1, 9)
                              from b in Enumerable.Range(a + 1, 9 - a)
                              select new { A = a, B = b, 积 = a * b, 和 = a + b };
                var 甲说不知道时 = from u in 老师可能出的题
                             where 老师可能出的题.Any(x => x.A != u.A && x.积 == u.积)
                             select u;
                Console.WriteLine("----------甲说不知道时");
                foreach (var result in 甲说不知道时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                var 乙说不知道时 = from u in 甲说不知道时
                             where 甲说不知道时.Any(x => x.A  != u.A  && x.和 == u.和)
                             select u;
                Console.WriteLine("----------乙说不知道时");
                foreach (var result in 乙说不知道时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                var 甲说知道了时 = from u in 乙说不知道时
                             group u by u.积 into g
                             where g.Count() == 1
                             select g.First();
                Console.WriteLine("----------甲说知道了时");
                foreach (var result in 甲说知道了时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                var 乙说知道了时 = from u in 甲说知道了时
                             group u by u.和 into g
                             where g.Count() == 1
                             select g.First();
                Console.WriteLine("----------乙说知道了时");
                foreach (var result in 乙说知道了时)
                    Console.WriteLine("A={0}, B={1}", result.A, result.B);
                Console.ReadKey();
            }
        }
    }
      

  18.   

    告诉一个积,,,就只有3组方案的案中的一个
    2*9=18
    3*62*6=12
    3*43*8=24
    4*6答案应该只有一个..当然要先知道 积 and 和 呀~~~~~~~~~~~~~~~~~~~~~
    18 and 11 =2/9
    18 and 9 =3/612 and 8 =2/6   
    12 and 7 =3/424 and 11 =3/8 (注:这组中和11和组一重复了....^_^)
    24 and 10 =4/6甲知道积说不知道数字,已听了之后就会去分析答案.他会做很多假设..如果积是18 or 12 or 24以上只有一种情况已才是不知道...那就是和为11时.事实的确是11,两个答案而已不确认是哪个只能说我也不知道,而甲听了已说不知道后,就知道已的和是11,因为甲知道积,所以他知道答案了,
    如果积是18.他的答案就是2/9.如果积是24答案就是3/8而题目中最后[已又说我知道],其实应该是错的,,已还是不知道
    假设积是18 和是 11 ,已知道了,那答案是哪个,他不知道积,18,24都是满足条件