poj1006 Biorhythms 中国剩余定理
参考:http://blog.csdn.net/lyy289065406/article/details/6648551
有中文翻译.
思路:中国剩余定理.
中国剩余定理:
在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?”这个问题称为“孙子问题”,该问题的一般解法国际上称为“中国剩余定理”。
求解思路:
- 求出除3余1的a3, 且满足a3 / 5 == 0 && a3 / 7 == 0.很显然满足条件的a3 可以是: a3 = 5 * 3 * k, 求出 k 即可.
- 然后依次求得满足除5余1的a5, 除7余1的a7.
- 之前都是余1, 而三三数之剩二, 所以a3还需要乘以2, 即 a3 = a3 * 2, 同理, a5 *= 3, a7 *= 2.
- 那么a = a3+ a5 + a7 即是一个满足"孙子问题"的一个解.
- 但在这里我们要求得是最小解我们因此还需要除3, 5, 7的最小公倍数. 即 a %= lcm(3, 5, 7) .
本题思路:
- 体力p、感情e 和智力i 周期,它们的周期长度为23天、28天和33天,那么lcm(23, 28, 33) = 21252.
- p23 = 5544, e28 = 14421,i33 = 1288.
- a = (p23*p + e28*e + i33*i - d + 21252) % 21252
1 #include <iostream> 2 using namespace std; 3 /* 4 a, b 的最大公约数 5 */ 6 int lcm(int a, int b) 7 { 8 int s = a * b; 9 int t; 10 while (b) 11 { 12 t = a % b; 13 a = b; 14 b = t; 15 } 16 return s / a; 17 } 18 19 /* 20 求得sum, 21 a | sum && b | sum && sum % r == 1 22 */ 23 int China(int a, int b, int r) 24 { 25 int t = lcm(a, b); 26 int sum = t; 27 while (sum % r!= 1) 28 { 29 sum += t; 30 } 31 return sum; 32 } 33 34 int main() 35 { 36 37 int p, e, i, d; 38 //cout<<lcm(lcm(23, 28), 33)<<endl; 39 int lcm = 21252; 40 //cout<<China(23, 28, 33)<<endl; 41 int i33 = 1288; 42 //cout<<China(28, 33, 23)<<endl; 43 int p23 = 5544; 44 //cout<<China(33,23,28)<<endl; 45 int e28 = 14421; 46 int t; 47 int cnt = 0; 48 while (cin>>p>>e>>i>>d) 49 { 50 if (p == -1 && e == -1 && i == -1 && d == -1) 51 break; 52 t = (p*p23 + e * e28 + i * i33 - d + lcm) % lcm; 53 t = t == 0 ? lcm : t; 54 cout<<"Case "<<++cnt<<": the next triple peak occurs in "<<t<<" days."<<endl; 55 56 } 57 return 0; 58 }