poj1006 Biorhythms 中国剩余定理
首先清楚中国剩余定理
在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以3 余2),五五数之剩三(除以5 余3),七七数之剩二(除以7 余2),问物几何?”
做这个问题之前,首先要清楚两条定理
- 如果有a%b=c,则有(a+k b)%b=c(k 为非零整数)。两个数相加,如果存在一个加数,不能被整数a整除,那么它们的和,就不能被整数a整除。
- 如果a%b=c,那么(a*k)%b=(a%b+a%b+„+a%b)%b=(c+c+„+c)%b=kc%b(k>0)。两数不能整除,若除数扩大(或缩小)了几倍,而被除数不变,则其商和余数也同时扩大(或缩小)相同的倍数(余数必小于除数)
例: 使33×28×a被23除余1,用33×28×6=5544;
使23×33×b被28除余1,用23×33×19=14421;
使23×28×c被33除余1,用23×28×2=1288。
因为33×28,被23除余4,为了让33×28×a被23除余1,所以根据定理2取33×28×6.
我们在计算乘法逆元时,经常使用拓展欧几里得算法
这是我认为的一篇写得比较好的关于拓展欧几里得算法的博客
https://blog.csdn.net/leader_one/article/details/75222771
poj1006 Biorhythms
#include<stdio.h>
#include<math.h>
int main(void)
{
int p,e,i,d,x,n=1;
while(scanf("%d%d%d%d", &p, &e, &i, &d) != EOF && p != -1&& e != -1&& i != -10&& d != -1)
{
p=p%23;
e=e%28;
i=i%33;
int t=5544*p+14421*e+1288*i;//这里直接算出28*33*6等,省略了求乘法逆元的步骤 //
x=t%21252-d;
while(x<=0)
{
t=t%21252+21252;
x=t-d;
}
printf("Case %d: ",n);
printf("the next triple peak occurs in %d days.\n", x);
n++;
}
}