问题链接:PKU1006
本题可以直接用中国剩余定理来解,同余方程如下:
X≡p(mod 23)
X≡e(mod 28)
X≡i(mod 33)
其中,23、28和33是两两互素的,满足中国剩余定理的前提条件。
#include <stdio.h> // 递推法实现扩展欧几里德算法 long exgcd(long a, long b, long *x, long *y) { long x0=1, y0=0, x1=0, y1=1; long r, q; *x=0; *y=1; r = a % b; q = (a - r) / b; while(r) { *x = x0 - q * x1; *y = y0 - q * y1; x0 = x1; y0 = y1; x1 = *x; y1 = *y; a = b; b = r; r = a % b; q = (a - r) / b; } return b; } // 扩展欧几里德算法求逆元 long minv(long a, long p) { long x, y; exgcd(a, p, &x, &y); return x<0 ? x+p : x; } // 中国剩余定理(Chinese remainder theorem, CRT) long crt(long a[], long m[], int n) { long bm=1, subm[n], x=0; int i; for(i=0; i<n; i++) bm *= m[i]; for(i=0; i<n; i++) subm[i] = bm / m[i]; for(i=0; i<n; i++) { x += subm[i] * minv(subm[i], m[i]) * a[i]; x %= bm; } return x; } int main(void) { long p, e, i, d; long a[3], m[3]; long x, bm; int ncase = 1; for(;;) { scanf("%ld%ld%ld%ld", &p, &e, &i, &d); if(p==-1 && e==-1 && i==-1 && d==-1) break; a[0] = p; a[1] = e; a[2] = i; m[0] = 23; m[1] = 28; m[2] = 33; bm = 23 * 28 * 33; x = crt(a, m, 3); while(x<=d) x += bm; printf("Case %d: the next triple peak occurs in %ld days.\n", ncase++, x-d); } return 0; }