中国剩余定理,即孙子定理,对于三个数问题的形式为:已知M1,M2,M3是两两互素的正整数,求最小ans,使它被M1,M2, M3所除得到的余数分别是C1,C2, C3。
孙子定理的算法思想是:找出被Mi除余1而被另外两个数整除的数Wi。所求数之一为:ans = sum(Wi*Ci)(i = 1,2,3).若要求满足条件的最小解,mod(lcm(M1,M2 ,M3 ))即可。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 4;
int M[N]={23, 28, 33}, C[N], W[N], day;
int mod(int a, int b, int c) {
int tmp,t;
tmp = a*b;
t = tmp;
while (tmp%c != 1)
tmp += t;
return tmp;
}
int main()
{
int i, ca, cnt;
scanf("%d", &ca);
for (i = 1; i <= ca; ++i) {
cnt = 0;
while (scanf("%d %d %d %d", &C[0], &C[1], &C[2], &day)) {
if (C[0] == -1 && C[1] == -1 && C[2] == -1 && day == -1)
break;
W[0] = mod(M[1], M[2], M[0]);
W[1] = mod(M[0], M[2], M[1]);
W[2] = mod(M[0], M[1], M[2]);
int ans = 0, j;
for (j = 0; j < 3; ++j)
ans += W[j]*C[j];
ans = (ans-day+21252)%21252;
if (ans == 0)
ans = 21252;
printf("Case %d: the next triple peak occurs in %d days.\n", ++cnt, ans);
}
if (i < ca)
printf("\n");
}
return 0;
}