您的位置:首页 > 其它

POJ1006,中国剩余定理

2007-08-04 09:43 489 查看
此题是中国剩余定理的典型应用,具体解法是:

对于给定的p,e,i,他们分别是除23,28,33的余数。问题就是求除23余p,除28余e,除33余i,的最小数。是不是很熟悉啊,当然你也可以手算然后在用程序输出,不过这样做就没什么意思了。先求除23余p,除28余e的最小公共数。for循环求出p+23*i==e+28*j,即最小数minpe=p+23*i,公共数为minpe+gcd(23,28)*x,相同的方法在与最后一个数进行条件合并,最后可求得minpei+gcd(gcd(23,28),33)*x;我们想要的就是minpei+gcd(gcd(23,28),33);解毕.

POJ1006 code:

#include<iostream>
#define physical 23
#define emotional 28
#define mental 33

int gcd(int a,int b){
int t1=a,t2=b,t;
while(a%b!=0){
t=a%b;
a=b;
b=t;
}
return (t1*t2)/b;
}
int main(){
int p,e,i,d,j,k,P=1;
while(scanf("%d%d%d%d",&p,&e,&i,&d)&&!(p==-1&&e==-1&&i==-1&&d==-1)){
int pe=gcd(physical,emotional),minpe;

for(j=0,k=0;;){
if((p+physical*j)==(e+emotional*k))
break;
if((p+physical*j)<(e+emotional*k))
j++;
if((p+physical*j)>(e+emotional*k))
k++;
}

minpe=p+physical*j;
int pei=gcd(pe,mental),minpei;
for(j=0,k=0;;){
if((minpe+pe*j)==(i+mental*k))
break;
if((minpe+pe*j)<(i+mental*k))
j++;
if((minpe+pe*j)>(i+mental*k))
k++;
}
minpei=i+mental*k;
if((minpei+pei-d)%pei==0)
printf("Case %d: the next triple peak occurs in %d days.\n",P++,pei);
else
printf("Case %d: the next triple peak occurs in %d days.\n",P++,(minpei+pei-d)%pei);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: