POJ1006 Biorhythms
题目来源:http://poj.org/problem?id=1006
题目大意:
有人认为人的一生中自TA出生开始有三种周期。这三种周期分别是生理周期,情绪周期和智力周期。他们的周期长度分别是23天、28天和33天。每个周期中有一个峰值。每个周期取得峰值时人在这个方面的表现最佳。
这三个周期有着不同的周期长度,所以三个周期的峰值出现的时间通常也不相同。我们希望找出一个人“三峰值点”(三个周期同时出现峰值的时间)。
对于每个人,你将知道该人今年里每个周期的峰值的一次出现时间(离今年开始的天数,不一定是第一次出现的时间)。你还会知道一个日期(也是离今年开始的天数),任务是求出给定的该日期后出现的第一个“三峰值点”。给定日期不计入在内。(比如,给定的日期是10,下一个“三峰值点”出现在第12天,那么答案是2而不是3.如果给定日期恰是“三峰值点”,则应该计算下一个“三峰值点”。)
输入:给定一组测试用例,每个用例一行,含4个整数p, e, i, d。p, e, i分别是今年开始后出现生理、情绪和智力峰值的时间点,d是给定的日期,有可能比p, e, i小,所有的值都是非负数,且不大于365,你可以假设一个“三峰值点”会在给定日期后的21252天内出现。输入以-1 -1 -1 -1结束。
输出:以Example Output的格式输出,即使天数为1也使用复数形式的days.
Sample Input
0 0 0 0 0 0 0 100 5 20 34 325 4 5 6 7 283 102 23 320 203 301 203 40 -1 -1 -1 -1
Sample Output
Case 1: the next triple peak occurs in 21252 days. Case 2: the next triple peak occurs in 21152 days. Case 3: the next triple peak occurs in 19575 days. Case 4: the next triple peak occurs in 16994 days. Case 5: the next triple peak occurs in 8910 days. Case 6: the next triple peak occurs in 10789 days.
解题关键:
1.给定的三个周期长度是互质的,这表明“三峰值点”出现的周期应该为三个小周期长度之积。
2.求三个周期的峰值同时出现的点,可以先求两个小周期峰值同时出现的点,再将这两个小周期合并为一个大周期再与第三个小周期求峰值同时出现的点,即三峰值点。
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1006 Biorhythms 3 // Memory: 740K Time: 110MS 4 // Language: G++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 using namespace std; 9 10 int main() { 11 int p, e, i, d, cases=0; 12 13 cin >> p >> e >> i >> d; 14 while (p != -1) { 15 cases++; 16 //求p, e峰值同时出现的点 17 while ((p - e) % 28 != 0) 18 p += 23; 19 //求p, e, i峰值同时出现的点 20 while ((p - i) % 33 != 0) 21 p += 23 * 28; 22 //求d前出现的最后一个三峰值点 23 while (p > d) 24 p -= 23 * 28 * 33; 25 //求d后出现的第一个三峰值点 26 while (p <= d) 27 p += 23 * 28 * 33; 28 cout << "Case " << cases << ": the next triple peak occurs in "; 29 cout << (p - d) << " days." << endl; 30 cin >> p >> e >> i >> d; 31 } 32 return 0; 33 }