很早就知道中国剩余定理了,也写过这类题,以前却都是暴力写过的。今天终于用定理写了一次。
剩余定理是关于:求某个数X,它对三个数(x,y,z。互素)取余分别为a,b,c。
解法为:
先计算出某个最小整数(px),它能整除另外两个数(y,z),但对该数(x)取余为1。然后累加三个最小整数(px,py,pz)与对应余数的积。累加和对三个数的最小公倍数取余结果即为所求X。
证明:
令T1=px*a,T2=py*b,T3=pz*c;
因为 px%x==1 ;所以 T1%x==a;
已知: T2%x==0,T3%x==0,T1%x==a; 所以X%x==a;
因为:T1%y==0,T3%y==0,T2%y==b;所以X%y==b;
同理:X%z==c; 【来自百度百科】
题意:
求X,X对23,28,33取余分别为a,b,c.需要注意的是,ans会小于d。
代码:
#include<iostream> #include<stdio.h> using namespace std; int main() { int a,b,c,d; while(scanf("%d%d%d%d",&a,&b,&c,&d)&&(a+b+c+d)!=-4) { a%=23;//余数 b%=28;//余数 c%=33;//余数 int ans=0; //5544 对28、33取余为0,对23取余为1 //14421对23、33取余为0,对28取余为1 //1288 对23、28取余为0,对33取余为1 ans=(5544*a+14421*b+1288*c)%21252; if(ans==0) printf("%d\n",21252-d); else if(ans<=d) printf("%d\n",ans+21252-d); else printf("%d\n",ans-d); } return 0; }