首先介绍一下中国剩余定理,在寒假回来的飞机上曾经看过证明……但是看着看着就睡着了……先把方法写上,证明以后再补吧……(虽然也只会最简单的三个数的,还互素……)
中国剩余定理介绍了这样一个问题,有这样一个数x,x%a=a1,x%b=b1,x%c=c1,求这个数x。(a,b,c互素)
首先求出三个数的逆元a2,b2,c2,如,a的逆元a2就是b1*c1*a2%a==1;
于是这个数可以表示为b1*c1*a2+a1*c1*b2+a1*b1*c2
当然,这个数%(a+b+c)后是最小的满足三个余数算式的数
hdu1370
这个题目的意思是给出a1,b1,c1与一个天数d,让你求出最小的大于d的数x,满足x%23=a1,x%28=b1,x%33=c1
代码如下
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
int main(int argc, char const *argv[])
{ int ans[5]={0,28*33,23*33,23*28};
int inv[4];
int ans1=28*33*23;
int a[4],b[5];
int i,j,k,m,n,t;
i=1; //求出逆元
while(ans[1]*i%23!=1)i++;
inv[1]=i;
i=1;
while(ans[2]*i%28!=1)i++;
inv[2]=i;
i=1;
while(ans[3]*i%33!=1)i++;
inv[3]=i;
scanf("%d",&t);
//printf("niyuan:%d %d %d\n",inv[1],inv[2],inv[3]);
while(t--)
{getchar();int cnt=0;
while(~scanf("%d%d%d%d",b+1,b+2,b+3,b+4))
{ int sum=0;
if(b[1]==-1 && b[1]==b[2] && b[2]==b[3] && b[3]==b[4])break;
cnt++;
for(i=1;i<=3;i++)
sum=(sum+ans[i]*b[i]*inv[i])%ans1;
while(sum<=b[4])sum+=ans1;
printf("Case %d: the next triple peak occurs in %d days.\n",cnt,sum-b[4]);
}
}
return 0;
}