生理周期
问题描述:
人生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为23天、28天和33天。每一个周期中有一天是高峰。在高峰这天,人会在相应的方面表现出色。例如,智力周期的高峰,人会思维敏捷,精力容易高度集中。因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天。对于每个人,我们想知道何时三个高峰落在同一天。对于每个周期,我们会给出从当前年份的第一天开始,到出现高峰的天数(不一定是第一次高峰出现的时间)。你的任务是给定一个从当年第一天开始数的天数,输出从给定时间开始(不包括给定时间)下一次三个高峰落在同一天的时间(距给定时间的天数)。例如:给定时间为10,下次出现三个高峰同天的时间是12,则输出2(注意这里不是3)。
如果明白中国剩余定理,则这道题不会花费太多功夫,注意一些细节上的问题就行。
用例题来简单介绍中国剩余定理。
例题:三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
题目的意思:有1个数,除以3余2.除以5余4,除以7余2,这个数至少是多少?
除以3余2的数可以写成3n+2。
3n+2这样的数除以5余3,由于2除以5余2,所以要求3n除以5余1。(加数之余等于余数之加)
3n除以5余1,3除以5余3,要求n除以5余2**(乘数之余等于余数之乘)**,则n最小取2。
所以满足“除以3余2,除以5余4”的最小的数是3×5+2=8,
所有满足“除以3余2,除以8余4”的数都可以写成8+3×5×m。
要求8+15×m除以7余2,由于8除以7余1,所以要求15×m除以7余1。(加数之余等于余数之加)
15×m除以7余1,由于15除以7余1,所以要求m除以7余1 (乘数之余等于余数之乘),则m最小取1。
所以满足“除以3余2,除以5余3,除以7余2”的最小的数是8+15×1=23。
import java.util.Scanner;
public class Biorhythms {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int p, e, i, day;
int[] nums = new int[100];
int k = 1;
do {
//输入体力,情感,智力高峰出现的日子与给定的日子
//体力,情感,智力高峰出现的日子相当于中国剩余定理中的余数
p = in.nextInt();
e = in.nextInt();
i = in.nextInt();
day = in.nextInt();
//判断是否退出循环
if( p == -1 && e == -1 && i == -1 && day == -1) {
break;
}
//第一步
//计算满足前两个等式的最小的值
int n, temp;
int p1 = p % 28;
if(p1 > e) {
temp = e + 28 - p1;
}
else{
temp = (e - p1) % 28;
}
//计算满足等式的n的最小值
for(n = 0;; n++) {
if(23 * n % 28 == temp)
break;
}
int num = 23 * n + p;
//第二步
//计算满足最后一个等式的值
int n1, temp1;
int p2 = num % 33;
if(p2 > i) {
temp1 = i + 33 - p2;
}
else{
temp1 = (i - p2) % 33;
}
//计算满足等式的n1的最小值
for(n1 = 0;; n1++) {
if(23 * 28 * n1 % 33 == temp1)
break;
}
//到此为止,应用中国剩余定理完毕。
//计算与题目要求的日子。
for(int j = n1; ;j += 33) {
int num1 = num + 23 * 28 * j;
if(num1 > day) {
nums[k++] = num1 - day;
break;
}
}
}while(true);
//输出
for(int count = 1; count < k; count++) {
System.out.println("Case " + count + ":the next triple peak "
+ "occurs in " + nums[count] + " days");
}
}