问题链接:HDU1370 Biorhythms。
问题描述:参见上文。
问题分析:本题可以直接用中国剩余定理来解,同余方程如下:
X≡p(mod 23)
X≡e(mod 28)
X≡i(mod 33)
其中,23、28和33是两两互素的,满足中国剩余定理的前提条件。
程序说明:
这个题的原题应该是UVALive5421。
这个题与《POJ1006 UVA756 UVALive5421 Biorhythms》略有不同,就是需要输入起始case号,其他完全相同。
参考链接:POJ1006 UVA756 UVALive5421 Biorhythms
AC的C++语言程序:
/* HDU1370 Biorhythms */ #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, mi, x=0; int i; for(i=0; i<n; i++) bm *= m[i]; for(i=0; i<n; i++) { mi = bm / m[i]; x += a[i] * mi * minv(mi, m[i]); x %= bm; } return x; } int main(void) { long p, e, i, d; long a[3], m[3]; long x, bm; int caseno; scanf("%d", &caseno); 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. ", caseno++, x-d); } return 0; }