Poj--1006(中国剩余定理)
2014-11-23 22:52:33
思路:建立三条同余方程:
28 * 33 * a % 23 == 1
23 * 33 * b % 28 == 1
23 * 28 * c % 33 == 1
设 v1 = 28 * 33 * a,则v1是28 * 33相对于23的数论倒数。依次类推有v1,v2,v3。
那么答案就是 ans = v1 * p + v2 * e + v3 * i,因为要最小还要使得ans - d >= 0,若ans为负时要累加23 * 28 * 33,之后 ans = ans % (23 * 28 * 33),以保证最小。
1 /************************************************************************* 2 > File Name: p1006.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Fri 21 Nov 2014 04:54:06 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 27 int p,e,i,d; 28 int v1,v2,v3; 29 int lcm = 23 * 28 * 33; 30 31 void Pre(){ 32 int sum = 0; 33 for(int i = 1; ;++i){ 34 sum += 28 * 33; 35 if(sum % 23 == 1){ 36 v1 = sum; 37 break; 38 } 39 } 40 sum = 0; 41 for(int i = 1; ; ++i){ 42 sum += 23 * 33; 43 if(sum % 28 == 1){ 44 v2 = sum; 45 break; 46 } 47 } 48 sum = 0; 49 for(int i = 1; ; ++i){ 50 sum += 23 * 28; 51 if(sum % 33 == 1){ 52 v3 = sum; 53 break; 54 } 55 } 56 } 57 58 int main(){ 59 Pre(); 60 int Case = 0; 61 while(scanf("%d%d%d%d",&p,&e,&i,&d) != EOF){ 62 if(p == -1 && e == -1 && i == -1 && d == -1) 63 break; 64 int ans = p * v1 + e * v2 + i * v3; 65 if(ans > 0){ 66 ans %= lcm; 67 } 68 while(ans <= d) ans += lcm; 69 ans -= d; 70 printf("Case %d: the next triple peak occurs in %d days.\n",++Case,ans); 71 } 72 return 0; 73 }