韩信点兵
来源:互联网 发布:路由器访客网络是什么 编辑:程序博客网 时间:2024/05/20 18:03
韩信点兵
描述
相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入3个非负整数a,b,c ,表示每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100 。
输入
输入3个非负整数a,b,c ,表示每种队形排尾的人数(a<3,b<5,c<7)。例如,输入:2 4 5
输出
输出总人数的最小值(或报告无解,即输出No answer)。实例,输出:89
样例输入
2 1 6
样例输出
41
由题
我们已经知道了总兵数x对3,5,7取模得到的余数a,b,c
则可列出一个同余方程组
x≡a(mod 3)
x≡b(mod 5)
x≡c(mod 7)
通过题意列出方程组,最后可以解得x
用求解同余方程组的思路涉及到以下知识:
- 数论倒数
- 孙子定理
依据孙子定理
若有
x≡a1(mod m1)
x≡a2(mod m2)
x≡a3(mod m3)
.
.
.
x≡an(mod mn)
且m1,m2…mn两两互质令M=m1*m2*…*mi
Mi=M/mi (1<=i<=n)
再求得每一个Mi的数论倒数为ti
则有
为x的解集
具体思路如下:
已知
x≡a(mod 3)
x≡b(mod 5)
x≡c(mod 7)
令
M=3*5*7
Ma=M/3;
Mb=M/5;
Mc=M/7;
对于每一个Ma,Mb,Mc;
求他们的数论倒数ta,tb,tc;
最后列式
x=k*M+a*ta*Ma+b*tb*Mb+c*tc*Mc (k取整数值并且能使x大于零)
即可通过找到符合条件的k值,来求得x
求数论倒数的方法:
设Ma对于p的数论倒数为ta,有
ta=Ma^(p-2) (mod p)
即可求得数论倒数
以上为解题思路,解题过程如下:
设x为总的兵数,当输入a=2,b=1,c=6时
依题列方程组
x≡2(mod 3)
x≡1(mod 5)
x≡6(mod 7)
M=3*5*7=105
Ma=5*7=35
Mb=3*7=21
Mc=3*5=15
ta=35^(3-2)(mod 3)=2
tb=21^(5-2)(mod 5)=1
tc=15^(7-2)(mod 7)=1
∴x=105k+70a+21b+15c=105k+251
且总人数不小于10,不超过100
也就是k=-1或-2,取合适的值即可
无解
因为3,5,7两两互质,因此方程组有解,
但取值区间100-10+1=91<105
所以无解的情况应是x不在取值区间内
代码如下:
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>int main(){ int a,b,c,sum; while(scanf("%d %d %d",&a,&b,&c)==3){ sum=70*a+21*b+15*c-105; if(10<=sum&&sum<=100){ printf("%d\n",sum); }else if(10<=sum-105&&sum-105<=100){ printf("%d\n",sum-105); }else{ printf("No answer\n"); } } return 0;}
- //韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- 韩信点兵
- JAVA向上转型和向下转型(三)
- 如何将hive查询结果导出成txt文件
- 基础知识三
- AOP和动态代理
- ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES) 的解决方案
- 韩信点兵
- Linux学习笔记之目录的分类和意义
- java 日期
- Holding Bin-Laden Captive!
- 算法课第3周第1题——113. Path Sum II
- SSH整合一
- 在应用程序中调用控制台的方法
- DNS服务器列表
- Linux中的压缩命令