CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

一个有争议的算法,看你是怎么想的

楼主yuyuxiaoyu(左大S,右小S,偶居中)2006-05-22 10:42:30 在 C/C++ / C++ 语言 提问

以下是引用的前几天的一个帖子  
  -----------------------------------------------------------------------------------  
  主  题:     《振兴CB基础类,几道智力题,会C语言的都能做》      
  作  者:     ********      
   
  2)孙,庞斗智问题  
   
  孙膑,庞涓都是鬼谷子的徒弟;  
  一天鬼出了这道题目:他从2到99中选出两个不同的整数,把积告诉孙,把和告诉庞;  
  庞说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。  
  孙说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。  
  庞说:既然你这么说,我现在也知道这两个数字是什么了。  
   
  编程问这两个数字是什么?  
  -------------------------------------------------------------------------------  
  小弟对程序有疑问,觉得答案不是唯一,而他们的程序只解出了第一个解(最小解),请各位高人解惑!  
  附:   有谁知道vs2005的中文技术内幕在哪里下载?  
  问题点数:1、回复次数:29Top

1 楼yuyuxiaoyu(左大S,右小S,偶居中)回复于 2006-05-22 10:53:10 得分 0

以下是别人的思路;  
  -----------------------------------------------------------------解题思路1:  
   
  假设数为X,Y;和为X+Y=A,积为X*Y=B.  
  根据庞第一次所说的:“我肯定你也不知道这两个数是什么”。由此知道,X+Y不是两个素数之和。那么A的可能11,17,23,27,29,35,37,41,47,51,53,57,59,65,67,71,77,79,83,87,89,95,97.  
  我们再计算一下B的可能值:  
  和是11能得到的积:18,24,28,30  
  和是17能得到的积:30,42,52,60,66,70,72  
  和是23能得到的积:42,60...  
  和是27能得到的积:50,72...  
  和是29能得到的积:...  
  和是35能得到的积:66...  
  和是37能得到的积:70...  
  ......  
  我们可以得出可能的B为....,当然了,有些数(30=5*6=2*15)出现不止一次。  
   
  这时候,孙依据自己的数比较计算后,“我现在能够确定这两个数字了。”  
  我们依据这句话,和我们算出来的B的集合,我们又可以把计算出来的B的集合删除一些重复数。  
   
  和是11能得到的积:18,24,28  
  和是17能得到的积:52  
  和是23能得到的积:42,76...  
  和是27能得到的积:50,92...  
  和是29能得到的积:54,78...  
  和是35能得到的积:96,124...  
  和是37能得到的积:,...  
  ......  
  因为庞说:“既然你这么说,我现在也知道这两个数字是什么了。”那么由和得出的积也必须是唯一的,由上面知道只有一行是剩下一个数的,那就是和17积52。那么X和Y分别是4和13。  
   
   
  解题思路2:  
   
  说话依次编号为S1,P1,S2。  
  设这两个数为x,y,和为s,积为p。  
  由S1,P不知道这两个数,所以s不可能是两个质数相加得来的,而且s<=41,因为如果s>41,那么P拿到41×(s-41)必定可以猜出s了(关于这一点,参考老马的证明,这一点很巧妙,可以省不少事情)。所以和s为{11,17,23,27,29,35,37,41}之一,设这个集合为A。  
  1).假设和是11。11=2+9=3+8=4+7=5+6,如果P拿到18,18=3×6=2×9,只有2+9落在集合A中,所以P可以说出P1,但是这时候S能不能说出S2呢?我们来看,如果P拿到24,24=6×4=3×8=2×12,P同样可以说P1,因为至少有两种情况P都可以说出P1,所以A就无法断言S2,所以和不是11。  
  2).假设和是17。17=2+15=3+14=4+13=5+12=6+11=7+10=8+9,很明显,由于P拿到4×13可以断言P1,而其他情况,P都无法断言P1,所以和是17。  
  3).假设和是23。23=2+21=3+20=4+19=5+18=6+17=7+16=8+15=9+14=10+13=11+12,咱们先考虑含有2的n次幂或者含有大质数的那些组,如果P拿到4×19或7×16都可以断言P1,所以和不是23。  
  4).假设和是27。如果P拿到8×19或4×23都可以断言P1,所以和不是27。  
  5).假设和是29。如果P拿到13×16或7×22都可以断言P1,所以和不是29。  
  6).假设和是35。如果P拿到16×19或4×31都可以断言P1,所以和不是35。  
  7).假设和是37。如果P拿到8×29或11×26都可以断言P1,所以和不是37。  
  8).假设和是41。如果B拿到4×37或8×33,都可以断言P1,所以和不是41。  
  综上所述:这两个数是4和13。  
   
  解题思路3:  
   
  孙庞猜数的手算推理解法  
   
  1)按照庞的第一句话的后半部分,我们肯定庞知道的和S肯定不会大于54。  
   
  因为如果和54   恰好是53和a,那么孙知道的积M就是M=53*a,于是孙知道,这原来两个数中至少有  
  一个含有53这个因子,因为53是个素数。可是小于100,又有53这个因子的,只能是  
  53本身,所以孙就可以只凭这个积53*a推断出这两个数术53和a。所以如果庞知道的  
  S大于54的话,他就不敢排除两个数是53和a这种可能,也就不敢贸然说“但是我肯定  
  你也不知道这两个数是什么”这种话。  
   
  如果53+99  
   
  如果S=98+99,那么庞可以立刻判断出,这两个数只能是98和99,而且M只能是98*99,  
  孙也可以知道这两个术,所以显然不可能。  
   
  2)按照庞的第一句话的后半部分,我们还可以肯定庞知道的和S不可以表示为两个素数的和。  
   
  否则的话,如果鬼谷子选的两个数字恰好就是这两个素数,那么孙知道积M后,就可以得到唯一的素因子分解,判断出结果。于是庞还是不敢说“但是我肯定你也不知道这两个数是什么”这种话。  
   
  根据哥德巴赫猜想,任何大于4的偶数都可以表示为两个素数之和,对54以下的偶数,猜想肯定被验证过,所以S一定不能是偶数。  
   
  另外型为S=2+p的奇数,其中p是奇素数的那些S也同样要排除掉。  
   
  还有S=51也要排除掉,因为51=17+2*17。如果鬼谷子选的是(17,2*17),那么孙知道  
  的将是M=2*17*17,他对鬼谷子原来的两数的猜想只能是(17,2*17)。(为什么51要单独拿出来,要看下面的推理)  
   
  3)于是我们得到S必须在以下数中:  
  11172327293537414753  
   
  另外一方面,只要庞的S在上面这些数中,他就可以说“但是我肯定你也不知道这两个  
  数是什么”,因为这些数无论怎么拆成两数和,都至少有一个数是合数(必是一偶一  
  奇,如果偶的那个大于2,它就是合数,如果偶的那个等于2,我们上面的步骤已经保  
  证奇的那个是合数),也就是S只能拆成  
   a)S=2+a*b 或 b)S=a+2^n*b  
  这两个样子,其中a和b都是奇数,n>=1。  
  那么(下面我说的“至少两组数”中的两组数都不相同,而且的确存在(也就是那些  
  数都小于100)的理由我就不写了,根据条件很显然)  
   a)或者孙的M=2*a*b,孙就会在(2*a,b)和(2,a*b)至少两组数里拿不定主意(a和  
    b都是奇数,所以这两组数一定不同);  
   b)或者M=2^n*a*b,  
    如果n>1,那么孙就会在(2^(n-1)*a,2*b)和(2^n*a,b)至少两组数里拿不定主意;  
    如果n=1,而且a不等于b,那么孙就会在(2*a,b)和(2b,a)至少两组数里拿不定主  
    意;  
    如果n=1,而且a等于b,这意味着S=a+2*a=3a,所以S一定是3的倍数,我们只要  
    讨论S=27就可以了。27如果被拆成了S=9+18,那么孙拿到的M=9*18,他就会在  
    (9,18)和(27,6)至少两组数里拿不定主意。  
   (上面对51的讨论就是从这最后一种情况的讨论发现的,我不知道上面的论证是否  
   过分烦琐了,但是看看51这个“特例”,我怀疑严格的论证可能就得这么烦)  
   
  现在我们知道,当且仅当庞得到的和数S在  
  C={11,17,23,27,29,35,37,41,47,53}  
  中,他才会说出“我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数  
  是什么”这句话  
   
  孙膑可以和我们得到同样的结论,他还比我们多知道那个M。  
   
  4)孙的话“我现在能够确定这两个数字了”表明,他把M分解成素因子后,然后组合成  
  关于鬼谷子的那两个数的若干个猜想中,有且仅有一个猜想的和在C中。否则的话,他  
  还是会在多个猜想之间拿不定主意。  
   
  庞涓听了孙的话也可以得到和我们一样的结论,他还比我们多知道那个S。  
   
  5)庞的话“我现在也知道这两个数字是什么了”表明,他把S拆成两数和后,也得到了  
  关于鬼谷子的那两个数的若干个猜想,但是在所有这些拆法中,只有一种满足4)里的  
  条件,否则他不会知道究竟是哪种情况,使得孙膑推断出那两个数来。  
   
  于是我们可以排除掉C中那些可以用两种方法表示为S=2^n+p的S,其中n>1,p为素数。  
  因为如果S=2^n1+p1=2^n2+p2,无论是(2^n1,p1)还是(2^n2,p2)这两种情况,孙膑都  
  可以由M=2^n1*p1或M=2^n2*p2来断定出正确的结果,因为由M得到的各种两数组合,  
  只有(2^n,p)这样的组合,两数和才是奇数,从而在C中,于是孙膑就可以宣布自己知道  
  了是怎么回事,可庞涓却还得为(2^n1,p1)还是(2^n2,p2)这两种情况犯愁。  
   
  因为11=4+7=8+3,23=4+19=16+7,27=4+23=16+11,35=4+31=16+19,37=8+29=32+5,  
  47=4+43=16+31。于是S的可能值只能在  
  17294153  
  中。让我们继续缩小这个表。  
   
  29不可能,因为29=2+27=4+25。无论是(2,27)和(4,25),孙膑都可以正确判断出来:  
   a)如果是(2,27),M=2*27=2*3*3*3,那么孙可以猜的组合是(2,27)(3,18)(6,9),  
    后面两种对应的S为21和15,都不在C中,故不可能,于是只能是(2,27)。  
   b)如果是(4,25),M=4*25=2*2*5*5,那么孙可以猜的组合是(2,50)(4,25)(5,20)  
    (10,10)。只有(4,25)的S才在C中。  
  可是庞涓却要为孙膑的M到底是2*27还是4*25苦恼。  
   
  41不可能,因为41=4+37=10+31。后面推理略。  
   
  53不可能,因为53=6+47=16+37。后面推理略。  
   
  研究一下17。这下我们得考虑所有17的两数和拆法:  
  (2,15):那么M=2*15=2*3*5=6*5,而6+5=11也在C中,所以一定不是这个M,否则4)  
  的条件不能满足,孙“我现在能够确定这两个数字了”的话说不出来。  
  (3,14):那么M=3*14=2*3*7=2*21,而2+21=23也在C中。后面推理略。  
  (4,13):那么M=4*13=2*2*13。那么孙可以猜的组合是(2,26)(4,13),只有(4,13)  
  的和在C中,所以这种情况孙膑可以说4)中的话。  
  (5,12):那么M=5*12=2*2*3*5=3*20,而3+20=23也在C中。后面推理略。  
  (6,11):那么M=6*11=2*3*11=2*33,而2+33=35也在C中。后面推理略。  
  (7,10):那么M=7*10=2*5*7=2*35,而2+35=37也在C中。后面推理略。  
  (8,9):那么M=8*9=2*2*2*3*3=3*24,而3+24=27也在C中。后面推理略。  
   
  于是在S=17时,只有(4,13)这种情况,孙膑才可以猜出那两数是什么,既然如此,庞涓就知道这两个数是什么,说出“我现在也知道这两个数字是什么了”。听了庞涓的话,于是我们也知道,这两数该是(4,13)。  
  ----------------------------------------------------------------------------------Top

2 楼yuyuxiaoyu(左大S,右小S,偶居中)回复于 2006-05-22 11:31:41 得分 0

本人思路:  
  假设两个数为i,j;i+j=X;i*j=Y;  
  由庞第一句话,可以知道i,j为一奇一偶;  
  由孙第二局,知道,i=2(n)(2的n次方)   n>=2;   j为素数;同时i不能为2,2也是素数;  
  紧接着由第三局,知道   在X=i+j=?+?=...中,只有一组符合"   i=2(n)(2的n次方)   n>=2;   j为素数"  
  由著名的哥德巴赫猜想(大于4的偶数可以写成两个素数的和)=>即其本身X为素数;  
  现在知道   j,X为素数,且X=2(n)(n次方)+j;X不能为(2+素数),  
  由上条件和素数表得出   五组答案((4,13);(16,13);(4,37);(16,37);(16,43);)  
  无法取舍,请高手指点!谢谢!      
   
  附:   100以内素数表  
  2   3   5   7   11   13   17   19   23   29   31   37   41   43   47   53   59   61   67   71   73   79   83   89   97Top

3 楼yuyuxiaoyu(左大S,右小S,偶居中)回复于 2006-05-23 17:44:25 得分 0

嘿嘿   缪人来看哈?  
   
  TagTop

4 楼diedknight(diedknight)回复于 2006-05-23 21:19:04 得分 0

makeTop

5 楼iicup(双杯献酒)回复于 2006-05-23 23:17:47 得分 0

关注Top

6 楼iicup(双杯献酒)回复于 2006-05-23 23:41:44 得分 0

用程序计算,答案唯一:   (4,   13)  
   
  /*  
  孙膑,庞涓都是鬼谷子的徒弟;  
  一天鬼出了这道题目:他从2到99中选出两个不同的整数,把积告诉孙,把和告诉庞;  
  庞说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。  
  孙说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。  
  庞说:既然你这么说,我现在也知道这两个数字是什么了。  
   
  编程问这两个数字是什么?  
  */  
   
  /*  
  X,Y   在   0--99  
  S   =   X   +   Y  
  M   =   X   *   Y  
   
  //   条件1  
  S存在1种以上的和方法,故   S>2+3   &&   S<98+99  
   
  //   条件2  
  对任意   X1   +   Y1   =   S,   M1   =   X1   *   Y1,M都有另外一种分解方法  
  即X1和Y1中至少有1个是合数  
   
  //   条件3  
  M   =   X1*Y1   =   X2*Y2   ...   中,只有1个满足以上全部条件  
   
  //   条件4  
  S   =   X1+Y1   =   X2   +   Y2   ...   中,只有1个满足以上全部条件  
   
  */  
   
  /*  
  答案:  
  X   =   4  
  Y   =   13  
  S   =   17  
  M   =   52  
  */  
   
  #include   "stdafx.h"  
  #include   <iostream>  
  using   namespace   std;  
   
  int   C4(int   S);  
  int   C3(int   M);  
  bool   C2_1(int   S);  
  bool   IsPrime(int   N);  
   
   
  int   _tmain(int   argc,   _TCHAR*   argv[])  
  {  
  for(int   X=2;X<=99;X++)  
  for(int   Y=X;Y<=99;Y++)  
  {  
  int   S   =   X+Y;  
  int   M   =   X*Y;  
   
  if(!C2_1(S))   continue;  
   
  if(C3(M)   !=   1)   continue;  
   
  int   nC4   =   C4(S);  
  if(nC4   ==   1)  
  {  
  //   正确解答  
  cout   <<   endl;  
  cout   <<   "X   =   "   <<   X   <<   endl;  
  cout   <<   "Y   =   "   <<   Y   <<   endl;  
  cout   <<   "S   =   "   <<   S   <<   endl;  
  cout   <<   "M   =   "   <<   M   <<   endl;  
  }  
   
  }  
  return   0;  
  }  
   
   
  //   质数判断  
  bool   IsPrime(int   N)  
  {  
  for(int   i=2;i*i<=N;i++)  
  {  
                  if(N%i   ==   0)   return   false;  
  }  
   
  return   true;  
  }  
   
  //   条件1,2  
  bool   C2_1(int   S)  
  {  
  bool   bRet   =   false;  
  if(   S<=2+3   ||   S   >=   98+99)   return   false;  
  for(int   X=2;   X<=S/2;   X++)  
  {  
  int   Y   =   S-X;  
  if(Y>99)   continue;  
  if(IsPrime(X)   &&   IsPrime(Y))   return   false;  
  }  
   
  //   满足条件1,2  
  return   true;  
  }  
   
  //   条件3  
  int   C3(int   M)  
  {  
  int   nNum   =   0;  
  for(int   X=2;X*X<=M;X++)  
  {  
  if(M%X   !=   0)   continue;  
  int   Y   =   M/X;  
  if(Y>99)   continue;  
                  if(C2_1(X+Y))   nNum++;  
  }  
  return   nNum;  
  }  
   
  //   条件4  
  int   C4(int   S)  
  {  
  int   nNum   =   0;  
  for(int   X=2;X<=S/2;X++)  
  {  
  int   Y   =   S-X;  
  if(Y>99)continue;  
  if(C3(X*Y)   ==   1)   nNum++;  
  }  
   
  return   nNum;  
  }  
   
  Top

7 楼cyblueboy83(爱情白痴—电脑迷)回复于 2006-05-24 00:03:09 得分 0

关注  
  Top

8 楼yuyuxiaoyu(左大S,右小S,偶居中)回复于 2006-05-24 00:17:32 得分 0

得出   五组答案((4,13);(16,13);(4,37);(16,37);(16,43);)  
  无法取舍,请高手指点!谢谢!    
  -----------------------------------  
  真的无法取舍哈!!    
  Top

9 楼sinall()回复于 2006-05-24 09:35:15 得分 0

http://blog.csdn.net/sinall/archive/2005/11/06/523800.aspx  
  欢迎讨论Top

10 楼hufangyu(芙蓉红泪)回复于 2006-05-24 09:49:52 得分 0

算得头都大了~  关注楼下的……  
  Top

11 楼crazy_lazy_pig(疯狂懒猪)回复于 2006-05-24 12:12:37 得分 0

题目还没看懂   :(  
   
  庞孙二人有没有把自己的数告诉对方?Top

12 楼aronzhou()回复于 2006-05-24 12:34:49 得分 0

庞说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。  
  ---------------------------  
  为什么确定是素数?Top

13 楼crazy_lazy_pig(疯狂懒猪)回复于 2006-05-24 15:11:09 得分 0

终于把题目弄懂了,两个人互相不知道对方的数字,如果知道那么根据韦达定理可以马上得到鬼的两个数。  
   
  二楼给出的分析我没有挑出任何毛病,至于以后几楼给出的所谓的5组解中只有第一组是对的,其他都有问题。现分析(16,13):  
   
  16+13=29,当然,29有很多种拆和方法,其中之一是4+25,此时4*25=100,假设孙拿到的是100,则孙会想100=20*5,而20+5=25=2+23,庞既然敢确定我也不知道这两数,说明他拿到的不是25,那么只能是100=4*25,两数是4,25,也就是说当孙拿到100的时候可以根据庞的话判断两数,显然当孙拿到16*13的时候同样可以根据庞的话判断两数;接力棒又回到了庞,   现在庞该认为孙是拿了100还是16*13呢?  
  紧随其后的两种情况可以类似得出,其中(16,37)讨论起来稍微复杂一点,就不再多述。  
  最后的(16,43)其和是59,庞是不敢排除53+6的可能性的,而此时53*3*2在因子都小于100的情况仅有一种可能,即53*6(见二楼解题思路三的第一步)。Top

14 楼crazy_lazy_pig(疯狂懒猪)回复于 2006-05-24 15:23:34 得分 0

惭愧啊,上午居然没心情看源代码,这么简单的问题给想复杂了。  
  iicup(双杯献酒)给出的源代码加入了漂亮的注释,算法一目了然,程序也写的清晰易读。代码以及结果都完全正确,这个问题到这一步已经没什么好讨论的了。  
   
  不知道谁写的代码,先崇拜一下,呵呵。Top

15 楼crazy_lazy_pig(疯狂懒猪)回复于 2006-05-24 15:26:45 得分 0

呵呵,没注意,程序有点问题,在main函数里的双重循环X和Y是可以取到相等值的(虽然这并不影响结果),这还是要改进的。Top

16 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-05-24 21:42:15 得分 0

这个问题到这一步已经没什么好讨论的了。  
  ===================================  
  to   crazy_lazy_pig(疯狂懒猪)    
   
  现在下结论还太早。我研究了一下,4和13不是唯一的答案。4和19是第二个答案:即庞知道和是23,孙知道积是76。            
   
  还有,我认为前面的所有推理是有问题的。  
  首先,从庞的话不能肯定和一定是素数,只能肯定和一定不是偶数。  
   
  庞知道和,但庞说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。  
  由此可得:把这个和分成的两个数的所有可能中,每一组的积都可以在2-99中找到  
  另两个数的积与它相同。  
  如果和是11,那么2*9==3*6,3*8==4*6,4*7==2*14,5*6==2*15,即孙不论知道积是18,还是  
  24,28,30,它都不能确定这个积是哪两个数的积。  
  具有11这种性质的数一定不是两个素数的和,所以和一定不是偶数  
  庞敢说这样的话,和一定在这些数中:  
  11,17,23,27,29,35,37,41,47,51,53,57,59,65,67,71,77,79,83,87,89,93,95  
  97,101,107,113,117,119,121,123,125,127,131,135,137,143,145,147  
  149,155,157,161,163,167,171,173,177,179,185,187,189,191,197  
  不全是素数,也不是所有的素数都在其中。Top

17 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-05-24 22:18:11 得分 0

现在我来论证,为什么庞知道和为23,孙知道积为76,孙可以推断出这两个数为4和19。  
  庞的第一句话决定了他知道的和这个数具有与11这个数一样的性质。即和一定在我上面列举的数中。  
  孙知道积为76,而76只能分解为4*19       和     2*38     ,2+38=40一定不是庞知道的和。4+19=23,这个23符合庞的第一句话。所以孙肯定这两个数是4和19。  
   
  现在看是否符合庞的最后一句话。  
  庞知道和为23,23=X+Y,若有Z=X*Y,则Z的其他因式Z=X1*Y1中,不会再有X1+Y1=W,这个W落在庞第一句话决定的所有数上。因为如果还有和落在这些数上,孙是猜不出具体的数的。  
  现在把23分成两个数的和的所有分解中,只有4和19满足这个条件,所以庞猜得出是4和19  
   
  23       Y表示只有这组数孙才可能猜出两个数字  
  2+21         3+14         N  
  3+20         5+12         N  
  4+19         2+38           Y  
  5+18         2+45           N  
  6+17         2+51           N  
  7+16         2+51           N  
  8+15         5+24           N  
  9+14         2+63         N  
  10+13       2+65         N  
  11+12       3+44       N  
   
  还有个估计的答案是庞知道和为35,孙知道积为96。  
  有兴趣的可以分析一下。  
   
  估计这样的数至少有30对。  
   
  Top

18 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-05-24 22:25:18 得分 0

如果和是11,那么2*9==3*6,3*8==4*6,4*7==2*14,5*6==2*15,即孙不论知道积是18,还是  
  24,28,30,它都不能确定这个积是哪两个数的积。  
   
  ================前面这句话这样说  
   
  如果和是11,那么2*9==3*6,3*8==4*6,4*7==2*14,5*6==2*15,即孙在庞开口前,不论知道积是18,还是24,28,30,它都不能确定这个积是哪两个数的积Top

19 楼caicaiWu(我有点菜)回复于 2006-05-24 23:30:12 得分 0

markTop

20 楼yuyuxiaoyu(左大S,右小S,偶居中)回复于 2006-05-25 00:52:46 得分 0

首先感谢大家讨论这个算法,谢谢!  
  本题用程序算不妥,逻辑有先后   ,而程序把先后忽略了,总在重复判断。Top

21 楼diedknight(diedknight)回复于 2006-05-25 20:30:20 得分 0

只有4,13这一组...Top

22 楼iicup(双杯献酒)回复于 2006-05-25 21:59:23 得分 0

孙膑,庞涓都是鬼谷子的徒弟;  
  一天鬼出了这道题目:他从2到99中选出两个不同的整数,把积告诉孙,把和告诉庞;  
  庞说:我虽然不能确定这两个数是什么,  
  /*  
  设  
  S   =   X   +   Y  
  M   =   X   *   Y  
  条件1:  
  S存在1种以上的和方法,所以   S>2+3   &&   S<98+99  
  */  
   
  但是我肯定你也不知道这两个数是什么。  
  /*,  
  条件2:  
  对任意的一种和分解:   S   =   Xi   +   Yi,   Xi和Yi中至少有一个是合数。  
  */  
   
  孙说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。  
  /*  
  条件3:  
  对所有积分解方法中:   M   =   Xj   *   Yj,   只有1种S=X+Y满足条件1和条件2  
  */  
   
  庞说:既然你这么说,我现在也知道这两个数字是什么了。  
  /*  
  条件4:  
  对任意一种和分解方法中:   S=Xi   +   Yi,只有1种M=X*Y满足条件1条件2和条件3。  
  */  
   
  只从人工计算应该很难.Top

23 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-05-26 00:02:46 得分 0

to   iicup(双杯献酒)    
   
  请你按你的理解分析一下我前面给出的和是23(4+19),积是76这组数吧,这也是我程序求出的。因为我的程序求出的有30多对数满足要求,所以我怀疑它的正确性。但23和76这组数,我手工分析是正确的,正如手工分析17(4+13)和42一样。Top

24 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-05-26 00:19:33 得分 0

to   iicup(双杯献酒)    
   
  谢谢,你不用分析了,我前面错把7*16   和2*51划等号了。Top

25 楼yuyuxiaoyu(左大S,右小S,偶居中)回复于 2006-05-26 00:24:51 得分 0

现在只剩下4组我有疑问    
   
   
  to     A_B_C_ABC(黄瓜):  
          23=4+19=16+7,这样就排除了Top

26 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-05-26 04:00:40 得分 0

大家BS我吧,居然把7*16   和2*51划等号  
  楼主结帖吧,下面是我独立完成的程序也证明只有4和13唯一的答案。  
   
  #include   <iostream.h>  
  bool   isPrime(int   n)  
  {  
  for(int   i=2;i*i<=n;i++)  
  if(n%i==0)   return   false;  
  return   true;  
  }  
   
   
  int   M[100];  
  void   isPang1()  
  {  
  cout<<"由庞第一句话决定了两数之和在下面这些数中:\n";  
          int   s=0;  
  for(int   i=5;i<=99+98;i+=2)  
  {  
  bool   flag=true;  
  for(int   k=2;k<=i/2;k++)  
  {  
  if(isPrime(k)   &&   isPrime(i-k))  
  {  
  flag=   false;  
  break;  
  }  
  }  
  if(flag)    
  {  
  cout<<i<<"     ";  
  M[s++]=i;  
  }  
  }  
  cout<<endl;  
  }  
  /*  
  孙说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。  
  现在孙知道积:它听庞说的话就能知道两个数,所以从孙知道的积   ,   分成的两个因子  
  的所有可能中只有一个的和对得到庞说的数的性质。如果孙知道的积是24,那么  
  只有3和   8的和11才符合庞说的数的性质,那么孙就可以确定这两个数为3和8。  
  假设孙知道的积是100,那么也只有25与4的和29才符合庞说的数的性质,那么  
  孙就可以确定这两个数为25和4。正如有人推断的4*13==2*26,只有4和13符合要求。  
   
   
  庞说:既然你这么说,我现在也知道这两个数字是什么了。  
  现在最关键的来了,庞根据孙推断得出,庞就推断得出,说明,根据庞知道  
  的和分成的两个数的所有可能中,只有一组产生的积X   ,将X分成的两个因子  
  的所有可能中只有一组产生的和会符合庞第一句话限定的数.而根据庞知道  
  的和分成的两个数的其他可能产生的积X,将X分成的两个因子的所有可能中  
  还有一组产生的和会符合庞第一句话限定的数.       假设庞知道和为17,那么可以  
  分成2和15,但2*15=30,但30可分成6*5,6+5=11,所心孙如果知道积  
    是30,是不能推断出是哪两个数的。所以庞就知道这两个数不可能是2和15。  
    同理,3*14=42,2*21=42,2+21=23,所以不可能是3和14。     .......  
     
  */  
   
   
  bool   chengFengjie(int   ji,int   n)//如果ji的所有因式只有一组的和符合庞第一句话决定的数,  
  {                                                               //则孙若知道ji,将可以算出ji=x*y中的x和y,返回true。  
  for(int   x=2;x*x<=ji;x++)  
  {  
  if(ji%x==0)  
  {  
  int   y=ji/x;  
  int   z=x+y;  
  if(z==n)    
  continue;  
  for(int   w=0;w<100;w++)//查找z是否在庞第一句话限定的所有数中  
  {  
  if(M[w]>z     ||   M[w]==0)//别找了,没有  
  break;  
  if(z==M[w])    
  {  
  return   false;//ji的所有因式有2组的和符合庞第一句话决定的数,  
  }  
  }//for   w  
  }  
  }  
  return   true;//找完所有的因式的和也没有找到第二组的和符合庞第一句话决定的数  
  }  
  void   JiaFengjie(int   n)//对数n进行加分解  
  {  
  int   Z=(n-3)/2;//对一个奇数n可以得到Z组加分解  
  int   Sun=0;  
  int   x=0,y=0;  
  for(int   i=2;i<=n/2;++i)  
  {  
  int   JI=i*(n-i);  
  if(chengFengjie(JI,n))  
  {  
  x=i;y=n-i;  
  Sun++;  
  }  
  }  
  switch(Sun)  
  {  
  case     0:  
  cout<<"出错。数字"<<n<<endl;  
  break;  
  case     1:  
  cout<<"答案是"<<x<<"   "<<y<<"   庞知道和为:"<<x+y<<"孙知道积为:"<<x*y<<endl;  
  break;  
  default:  
  cout<<n<<"不符合庞的第二句话。"<<endl;  
  break;  
  }  
  }  
   
  void   isPang2()  
  {  
  for(int   i=0;i<100;++i)  
  {  
  if(M[i]==0)   return   ;  
  JiaFengjie(M[i]);  
  }  
  }  
  int   main()  
  {  
  isPang1();  
  isPang2();  
  return   0;  
  }  
   
   
   
  Top

27 楼A_B_C_ABC(黄瓜@YouCanDoIt)回复于 2006-05-26 04:04:21 得分 0

 
  向出此题的人致敬!Top

28 楼oosky2004(我要好东西)回复于 2006-05-26 09:20:35 得分 0

执政Top

29 楼yuyuxiaoyu(左大S,右小S,偶居中)回复于 2006-05-27 08:54:59 得分 0

现在我们知道,当且仅当庞得到的和数S在  
  C={11,17,23,27,29,35,37,41,47,53}  
  中,他才会说出“我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数  
  是什么”这句话;  
  孙膑可以和我们得到"同样的结论",他还比我们多知道那个M。  
  --------------------------------------------------------------------------  
  这个推断好关键阿,绕来绕去都是第一局惹的祸,这点弄明白了,写不写程序都能推断出来;  
  你们的程序都很正确,非常感谢,我懂了!  
  在此,谨以五月的鲜花向你们致敬!Top

相关问题

关键词

得分解答快速导航

  • 帖主:yuyuxiaoyu

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo