题目大意:三个周期,长度为23,28,33.给定整数p,e,i表示三个周期高峰出现的时间,整数d表示一个给定的时间,求给定时间后至三个均达到高峰的时间之间的天数。
题目链接:http://poj.org/problem?id=1006&lang=zh-CN&change=true
题目可抽象为一个方程组:
(n+d)≡p (mod 23)
(n+d)≡e (mod 28)
(n+d)≡i (mod 33)
这是一个同余方程组,利用中国剩余定理(国内称孙子定理)可解。
以下定理内容说明来源于百度百科:
中国剩余定理说明:假设整数m1,m2, ... ,mn两两互质,则对任意的整数:a1,a2, ... ,an,方程组
有解,并且通解可以用如下方式构造得到:
设
是整数
m
1,
m
2, ... ,
m
n的乘积,并设
是除了
m
i以外的
n- 1个整数的乘积。
设
为
模
的数论倒数
:
方程组
的通解形式为
:在模
的意义下,方程组
只有一个解:
定理证明及其他应用请自行百度。
解该方程组,可知,
M=23*28*33=21252,M1=33*28=924,M2=23*33=759,M3=23*28=644.
t1=6,t2=19,t3=2.
n-d的通解为5544*p+14421*e+1288*i+k*21252.
n=5544*p+14421*e+1288*i+k*21252+d.
此题中取n的最小正解为结果。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int main()
{
int p,e,i,d;
int round=0;
while(scanf("%d%d%d%d",&p,&e,&i,&d))
{
round++;
if(p==-1&&e==-1&&i==-1&&d==-1)
break;
int n=(5544*p+14421*e+1288*i-d)%21252;
while(n<=0)
n+=21252;
printf("Case %d: the next triple peak occurs in %d days.\n",round,n);
}
return 0;
}