ex2_2 韩信点兵 (中国剩余定理)

来源:互联网 发布:知乎 葛巾 真人照 编辑:程序博客网 时间:2024/05/29 03:53

相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入包含多组数据,每组数据包含3个非负整数a,b,c,表示每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解,即输出No answer)。已知总人数不小于10,不超过100.输入到文件结束为止。
样例输入:
2 1 6
2 1 3
样例输出:
Case 1: 41
Case 2:No answer

法一

暴力求解枚举法

#include <iostream>#include <stdio.h>#include <math.h>#include <string.h>#include <algorithm>using namespace std;int main(){    int a, b, c;    int num = 0;    while(scanf("%d%d%d", &a, &b, &c) != EOF)    {        num++;        for(int i = 10; i <= 100; i++)        {            if(i % 3 == a && i % 5 == b && i % 7 == c)            {                printf("Case %d: %d\n", num, i);                break;            }            if(i == 100)printf("No answer\n");        }    }    return 0;}

法二

大衍求一术
大衍求一术

明朝数学家程大位在他所著的《算法统宗》中就暗示了此题解法:
三人同行七十稀,
五数梅花甘一枝,
七子团圆正半月,
除百零五便得知。
甘一是21,正半月是15,除百零五的意思就是求105的余数。这四句口诀的意思就是用任意两数的最小公倍数乘第三个数并求和,对和求105的余数即可得到答案。

这里求出来c1=2,c2=1,c3=1

#include <iostream>#include <stdio.h>#include <math.h>#include <string.h>#include <algorithm>using namespace std;int main(){    int a, b, c;    while(scanf("%d%d%d", &a, &b, &c) != EOF)    {        int m;        m = 70 * a + 21 * b + 15 * c;        m = m % 105;        if(m >= 10 && m <= 100)printf("%d\n", m);        else printf("No answer\n");    }    return 0;}
原创粉丝点击