题目大意:三个周期,长度为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,方程组
有解,并且通解可以用如下方式构造得到:
![](https://i-blog.csdnimg.cn/blog_migrate/babf8edb5b432dd4e69147432d9ebd4a.png)
设
是整数
m
1,
m
2, ... ,
m
n的乘积,并设
是除了
m
i以外的
n- 1个整数的乘积。
![](https://i-blog.csdnimg.cn/blog_migrate/fa9c62f87a1073ad8985077ad9a0c061.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7ae5dd1364cb9ebfea0da88b5cba9fec.png)
设
为
模
的数论倒数
:
![](https://i-blog.csdnimg.cn/blog_migrate/3f75b89817a73edf9a5a8d7b89d4799c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0eb0e8f9868e161642aee231037d95d9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3c8f1cdc34a27d53de9a7ac690087a70.png)
![](https://i-blog.csdnimg.cn/blog_migrate/55a95cc3409463671552fc8bfe873cae.png)
方程组
的通解形式为
:在模
的意义下,方程组
只有一个解:
![](https://i-blog.csdnimg.cn/blog_migrate/babf8edb5b432dd4e69147432d9ebd4a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/74aeab36832b96e114896f78d6a13647.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c76783792e2396a52172f1977a1817c6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/babf8edb5b432dd4e69147432d9ebd4a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/38df75ff1d3bc4a1b88842f076ca049a.png)
定理证明及其他应用请自行百度。
解该方程组,可知,
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;
}