首先介绍一下中国剩余定理,在寒假回来的飞机上曾经看过证明……但是看着看着就睡着了……先把方法写上,证明以后再补吧……(虽然也只会最简单的三个数的,还互素……)
中国剩余定理介绍了这样一个问题,有这样一个数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; }