问题描述:
人生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为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"); } }