ACM —— 1006 Biorhythms
2015-09-08 10:42
281 查看
解题代码:
中国剩余定理,本题难点不在编程,而是分析题目并转化为数学公式
要引入本题解法,先来看一个故事 “韩信点兵”:
传说西汉大将韩信,由于比较年轻,开始他的部下对他不很佩服。有一次阅兵时,韩信要求士兵分三路纵队,结果末尾多2人,改成五路纵队,结果末 尾多3人,再改成七路纵队,结果又余下2人,后来下级军官向他报告共有士兵2395人,韩信立即笑笑说不对(因2395除以3余数是1,不是2),由于已 经知道士兵总人数在2300~2400之间,所以韩信根据23,128,233,------,每相邻两数的间隔是105(3、5、7的最小公倍数),便 立即说出实际人数应是2333人(因2333=128+20χ105+105,它除以3余2,除以5余3,除以7余2)。这样使下级军官十分敬佩,这就是
韩信点兵的故事。
韩信点兵问题简化:已知 n%3=2, n%5=3, n%7=2, 求n。
再看我们这道题,读入p,e,i,d 4个整数
已知(n+d)%23=p; (n+d)%28=e; (n+d)%33=i ,求n 。
两道题是一样的。但是韩信当时计算出结果的?
韩信用的就是“中国剩余定理”,《孙子算经》中早有计算方法,大家可以查阅相关资料。
“韩信点兵”问题计算如下:
因为n%3=2, n%5=3, n%7=2
我们先找一个最小的数能被5和7整除,并且除以3的余数为1,这里,我们可以找到最小的数是70。有什么好处呢,大家知道70 * 1 % 3 = 1,那么70 * 2 % 3 = 2,70 * a % 3 = a,这样可以方便找到140这个除以3余数又为2的数,同时又能被5和7整除。
同理,我们可以找到21是能被3和7整除但是除以5余数是1的数,那么63便是除以5余数是3. 15能被3和5整除,但是除以7余数是1,那么30便是除以7余数是2的数。
那么 140 + 63 + 30 = 233,必定是一个除以3余数是2,除以5余数是3,除以7余数是2的一个数,而我们又很容易知道233加上或者减去3,5,7的最小公倍数,得到的数同样满足这个性质。韩信已知士兵人数在2300~2400之间,所以只需要233 + i × lcm(3,5,7)= 233 + 105 * 20 = 2333.
同样,这道题的解法就是:
假设过n天后,三个生理周期同时到高峰。
已知(n+d)%23=p; (n+d)%28=e; (n+d)%33=i
使33×28×a被23除余1,用33×28×8=5544;
使23×33×b被28除余1,用23×33×19=14421;
使23×28×c被33除余1,用23×28×2=1288。
因此有(5544×p+14421×e+1288×i)% lcm(23,28,33) =n+d
又23、28、33互质,即lcm(23,28,33)= 21252;
所以有n=(5544×p+14421×e+1288×i-d)%21252
本题所求的是最小整数解,避免n为负,因此最后结果为n= [n+21252]% 21252
那么最终求解n的表达式就是:
n=(5544*p+14421*e+1288*i-d+21252)%21252;
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner stdin = new Scanner(System.in); int p,e,i,d,n; int num = 0; while (((p = stdin.nextInt()) != -1) && ((e = stdin.nextInt()) != -1) && ((i = stdin.nextInt()) != -1) && ((d = stdin.nextInt()) != -1)) { n = (5544*p+14421*e+1288*i-d+21252)%21252; System.out.printf("Case %d: the next triple peak occurs in %d days.%n", ++num, ((n == 0) ? 21252:n)); } } }
中国剩余定理,本题难点不在编程,而是分析题目并转化为数学公式
要引入本题解法,先来看一个故事 “韩信点兵”:
传说西汉大将韩信,由于比较年轻,开始他的部下对他不很佩服。有一次阅兵时,韩信要求士兵分三路纵队,结果末尾多2人,改成五路纵队,结果末 尾多3人,再改成七路纵队,结果又余下2人,后来下级军官向他报告共有士兵2395人,韩信立即笑笑说不对(因2395除以3余数是1,不是2),由于已 经知道士兵总人数在2300~2400之间,所以韩信根据23,128,233,------,每相邻两数的间隔是105(3、5、7的最小公倍数),便 立即说出实际人数应是2333人(因2333=128+20χ105+105,它除以3余2,除以5余3,除以7余2)。这样使下级军官十分敬佩,这就是
韩信点兵的故事。
韩信点兵问题简化:已知 n%3=2, n%5=3, n%7=2, 求n。
再看我们这道题,读入p,e,i,d 4个整数
已知(n+d)%23=p; (n+d)%28=e; (n+d)%33=i ,求n 。
两道题是一样的。但是韩信当时计算出结果的?
韩信用的就是“中国剩余定理”,《孙子算经》中早有计算方法,大家可以查阅相关资料。
“韩信点兵”问题计算如下:
因为n%3=2, n%5=3, n%7=2
我们先找一个最小的数能被5和7整除,并且除以3的余数为1,这里,我们可以找到最小的数是70。有什么好处呢,大家知道70 * 1 % 3 = 1,那么70 * 2 % 3 = 2,70 * a % 3 = a,这样可以方便找到140这个除以3余数又为2的数,同时又能被5和7整除。
同理,我们可以找到21是能被3和7整除但是除以5余数是1的数,那么63便是除以5余数是3. 15能被3和5整除,但是除以7余数是1,那么30便是除以7余数是2的数。
那么 140 + 63 + 30 = 233,必定是一个除以3余数是2,除以5余数是3,除以7余数是2的一个数,而我们又很容易知道233加上或者减去3,5,7的最小公倍数,得到的数同样满足这个性质。韩信已知士兵人数在2300~2400之间,所以只需要233 + i × lcm(3,5,7)= 233 + 105 * 20 = 2333.
同样,这道题的解法就是:
假设过n天后,三个生理周期同时到高峰。
已知(n+d)%23=p; (n+d)%28=e; (n+d)%33=i
使33×28×a被23除余1,用33×28×8=5544;
使23×33×b被28除余1,用23×33×19=14421;
使23×28×c被33除余1,用23×28×2=1288。
因此有(5544×p+14421×e+1288×i)% lcm(23,28,33) =n+d
又23、28、33互质,即lcm(23,28,33)= 21252;
所以有n=(5544×p+14421×e+1288×i-d)%21252
本题所求的是最小整数解,避免n为负,因此最后结果为n= [n+21252]% 21252
那么最终求解n的表达式就是:
n=(5544*p+14421*e+1288*i-d+21252)%21252;
相关文章推荐
- C语言---函数返回局部变量
- 线索二叉树
- 关于expandlistview的简单使用
- nginx和IIS的均衡负载
- ORA-10858:在要求输入数字处找到非数字字符
- Linux中的历史命令
- win7登陆密码忘记了的几种找回方法
- linux下配置管理FTP服务器
- Thinking in java 之:迭代器Iterator
- Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(2) 自己封装的Calendar接口 - 跨到对岸去
- ionic 进入二级目录以后隐藏底部导航栏(tabs)
- Package javax.ws.rs
- 【交换机在江湖】第十三章 VLAN划分篇
- Grunt 自动化部署之css、image、javascript、html压缩Gruntfile.js配置
- 【OpenGL图形开发】开始新的方向
- replace函数
- JVM基础 之温绍锦讲Java虚拟机基础
- 关于UI的TextView的及其子类一些方法
- 【转载】如何查詢Oracle版本?
- Shape详解