韩信点兵(一)
题目描述
这一日,快码佳编四兄弟姐妹来到了一个练武场,只见一员大将在点兵台上。原来那就是赫赫有名的韩信。相传韩
信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他
每次只掠一眼队伍的排尾就知道总人数了。输入3个非负整数a,b,c ,表示每种队形排尾的人(a<3,b<5,c<7),
输出总人数的最小值(或报告无解)。已知总人数不小于100,不到200 。
输入
输入3个非负整数a,b,c ,表示每种队形排尾的人数(a<3,b<5,c<7)。
输出
输出总人数的最小值(或报告无解,即输出No answer)。
样例输入
0 0 0
样例输出
105
题解:
方法之一:可以利用“中国剩余定理”来解答。不知道大家有没有忘记其口诀“三人同行七十稀,五树梅花二十一,七子团圆正半月,除百零五便得知。”
1.三人同行七十稀:将除以3的余数乘以70;
2.五树梅花二十一:将除以5的余数乘以21;
3.七子团圆正半月:将除以7的余数乘以15(半个月);
4.除百零五便得知:将以上三个数字相加,最后除以105的余数。([3,5,7]=105)
证明:
70这个数字是5和7的倍数,并且除以3余1,也就是说,任何一个数添加一个70之后,不会改变除以5和7的余数,但是会在除以3的余数中多1。这样如果所求的数字除以3余2,就应该包含2个70,即70×2。
21这个数字是3和7的倍数,并且除以5余1, 也就是说,任何一个数添加了一个21之后不会改变除以3和7的余数,但是会在除以5的余数中多1。这样如果所求的数字除以5余3, 就应该包含3个21,即21×3。
15这个数字是3和5的倍数,并且除以7余1, 也就是说,任何一个数添加了一个15之后不会改变除以3和5的余数,但是会在除以7的余数中多1。这样如果所求的数字除以7余2, 就应该包含2个15,即15×2。
将以上三个数字相加得到233,就可以得到一个满足条件:除以3余2,除以5余3,除以7余2的数字。
105这个数字是3、5、7的公倍数,因此一个数字加上或者减去105之后,不会改变除以3、5、7的余数,因此在刚才得到的233上添加或者减去几个105,都是问题的解。
最终,通过口诀我们还是可以得到通解:23+105n,其中n=0,1,2,3…
源代码:
#include<stdio.h>
int main() {
int i=101,a,b,c;
scanf("%d%d%d",&a,&b,&c);
while(i<200) {
if((i%3==a)&&(i%5==b)&&(i%7==c)) {
printf("%d\n",i);
return 0;
}
i++;
}
printf("No answer\n");
}
AC