很早就知道中国剩余定理了,也写过这类题,以前却都是暴力写过的。今天终于用定理写了一次。
剩余定理是关于:求某个数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;
}