当前位置:嗨网首页>书籍在线阅读

04-五猴分桃

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

13.3 五猴分桃

问题描述

19.png 5只猴子一起摘了一堆桃子,因为太累了,它们商量决定先睡一觉再分。一会儿,第1只猴子来了,它见别的猴子没来,便将这堆桃子平均分成5份,结果多了1个,就将多的这个吃了,并拿走其中的1份。一会儿,第2只猴子来了,它不知道已经有1个同伴来过,还以为自己是第1个到的,于是将地上的桃子堆起来,再一次平均分成5份,发现也多了1个,同样吃了这1个桃子,并拿走其中1份。接着来的第3只、第4只、第5只猴子都是这样做的。

根据上面的条件,这5只猴子至少摘了多少个桃子?第5只猴子走后还剩下多少个桃子?

【分析】

设总的桃子数为S0,5只猴子分得的桃子数分别为S1、S2、S3、S4、S5,则有以下关系式,

S0=5S1+1

4S1=5S2+1

4S2=5S3+1

4S3=5S4+1

4S4=5S5+1

我们可以枚举桃子总数S0。从S5=1开始枚举,由S5得到S4,即S4=5S5+1,并判断S4是否能被4整除。如果能被4整除,则由S4得到S3,即S3=5S4+1;否则,将S5加1,继续以上过程。

以此类推,直到得到S0为止。此时,S0的值就是最少的总桃子数。

第13章\实例13-03.c
/********************************************
*实例说明:五猴分桃
*********************************************/
1  #include<stdio.h>
2  void main()
3  {
4      int s[6]={0},i;
5      for(s[5]=1;;s[5]++)
6      {
7          s[4]=5*s[5]+1;
8          if (s[4]%4)
9              continue;
10         else
11             s[4]/=4;
12         s[3]=5*s[4]+1;
13         if (s[3]%4)
14             continue;
15         else
16             s[3]/=4;
17         s[2]=5*s[3]+1;
18         if (s[2]%4)
19             continue;
20         else
21             s[2]/=4;
22         s[1]=5*s[2]+1;
23         if (s[1]%4)
24             continue;
25         else
26             s[1]/=4;
27         s[0]=5*s[1]+1;
28         break;
29     }
30     for(i=1;i<6;i++)
31         printf("第%d个猴子将桃子分为5堆,每堆%4d个桃子\n",i,s[i]);
32     printf("共摘了%d个桃子, 剩下%d个桃子\n", s[0], s[5]*4);
33 }

运行结果如图13.4所示。

372.png

图13.4 运行结果

【说明】

第5行从S[5]=1开始枚举,验证候选解是否是所求解。

第7行根据S[5]得到S[4]。

第8~11行判断S[4]是否能被4整除。如果不能被4整除,则说明S[4]不是所求解,需要继续验证下一个候选解,并将S[5]增1;否则,将S[4]除以4,得到S[4]。

第12行根据S[4]得到S[3]。

第13~16行判断S[3]是否能被4整除。如果不能被4整除,则说明S[3]不是所求解,需要继续验证下一个候选解,并将S[5]增1;否则,将S[3]除以4,得到S[3]。

第17~21行求出S[2]。

第22~26行求出S[1]。

第27行求出S[0]。

第28行跳出for循环语句。

第30~31行输出每只猴子分成的堆数、桃子个数。

第32行输出桃子的总个数和剩下的桃子个数。