韩信点兵的算术题目

参考:https://zhidao.baidu.com/question/1370246313435392139.html

 

在一千多年前的《孙子算经》中,有这样一道算术题:“今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?”按照今天的话来说:一个数除以3余2,除以5余3,除以7余2,求这个数。这样的问题,也有人称为“韩信点兵”。它形成了一类问题,也就是初等数论中的解同余式


①有一个数,除以3余2,除以4余1,问这个数除以12余几?
解:除以3余2的数有:2,5,8,11,14,17,20,23……
它们除以12的余数是:2,5,8,11,2,5,8,11……
除以4余1的数有:1,5,9,13,17,21,25,29……
它们除以12的余数是:1,5,9,1,5,9……
一个数除以12的余数是唯一的.上面两行余数中,只有5是共同的,因此这个数除以12的余数是5。如果我们把①的问题改变一下,不求被12除的余数,而是求这个数。很明显,满足条件的数是很多的,它是5+12×整数,整数可以取0,1,2,……,无穷无尽。
事实上,我们首先找出5后,注意到12是3与4的最小公倍数,再加上12的整数倍,就都是满足条件的数.这样就是把“除以3余2,除以4余1”两个条件合并成“除以12余5”一个条件。

《孙子算经》提出的问题有三个条件,我们可以先把两个条件合并成一个.然后再与第三个条件合并,就可找到答案。


②一个数除以3余2,除以5余3,除以7余2,求符合条件的最小数。
解:先列出除以3余2的数:2,5,8,11,14,17,20,23,26……
再列出除以5余3的数:3,8,13,18,23,28……
这两列数中,首先出现的公共数是8。3与5的最小公倍数是15。两个条件合并成一个就是8+15×整数,列出这一串数是8,23,38,……,再列出除以7余2的数2,9,16,23,30……就得出符合题目条件的最小数是23。
事实上,我们已把题目中三个条件合并成一个:被105除余23。

 

下面看一道无聊的题目:

滂沱大雨中,某司机途径一个十字路口,看到有一位老奶奶倒在地上,情况不明。他将车靠边停好后,打开行车记录仪,同时报了警和拨打120,然后上前给老奶奶撑伞,询问老奶奶的情况,并一直等到警察前来,将老奶奶送上了救护车,他才悄然驾车离去。警察通过查看监控录像,知道老奶奶是自己滑倒的,老奶奶的家人通过媒体寻找这位做好事不留名“任性”司机大哥。以下是几个事故现场目击者通过拨打电台热线电话对任性大哥的车牌号的描述。

甲说:我记得该车的车牌号码上有4位阿拉伯数字,而且第一位不是0。

乙说:我记得该车的车牌号码是小于1100的数。

丙说:我用该车牌号码除以3刚好余2。

丁说:我用该车牌号码除以5刚好余4。

戊说:我用该车牌号码除以7刚好余1。

根据题意在下画线处补充代码,完善程序,以便得出车牌号码。

 

问题分析:按照上面的论述,可以列出如下表格

 

所以只要计算出满足105x+29的数字即可。

代码如下:

 1 #include <stdio.h>
 2 void fun1()
 3 {
 4     int i;
 5     for(i=1000;i<=1100;i++)
 6     {
 7         if(i%3==2 && i%5==4 && i%7==1)
 8         {
 9             printf("form fun1: res=%d\n",i);
10         }
11     }
12 }
13 void fun2()
14 {
15     int i;
16     for(i=1000;i<=1100;i++)
17     {
18         if(i%105==29)
19         {
20             printf("form fun2: res=%d\n",i);
21         }
22     }
23 }
24 int main(int argc, char *argv[])
25 {
26     fun1();
27     fun2();
28     return 0;
29 }

运行结果:

 

posted on 2018-04-19 11:12  华山青竹  阅读(3188)  评论(0编辑  收藏  举报

导航