首页 > 代码库 > POJ1006同余定理
POJ1006同余定理
想哀号一声。。。- -
//找到k1%23,k2%28,k3%33均为1的三个数
#include<cstdio>
int main(){
int i=1,j=1,k=1;
while((33*28*i-1)%23!=0)
i++;
while((23*33*j-1)%28!=0)
j++;
while((23*28*k-1)%33!=0)
k++;
printf("%d %d %d",33*28*i,23*33*j,23*28*k);
return 0;
}
结果为:5544,14421,1288. 且23*28*33=21252。
解题思路:
算出三个数k1,k2,k3,使得:
K1%23==1
K2%28==1
K3%33==1
再 (k1*p+k2*e+k3*i-d)%(23*28*33),得到结果。此方法的前提:给定的三个数互质,如23,28,33。
题目是为了求出满足p+23*t1=e+28*t2=i+33*t3=s中最小的s,与d之间的间隔天数。
则需要s%23=p,s%28=e,s%33=i
所用公式:如果a%b=c则有:
1.(a+kt)%b=c
2.(a*k)%b=a%b+a%b+…+a%b=c+c+…+c=kc(k>0) 所以找出除以23,28,33余数为1的数后再乘上p,e,i,即是找到了除以23,28,33余数为p,e,i的数。
终于是有点理解了。。这个题好像马马虎虎的遇到好几次了。。
代码如下:
#include<cstdio>
int main(){
int p,e,i,d,n=0;
int s=0;
while(scanf("%d%d%d%d",&p,&e,&i,&d)){
if(p==-1&&e==-1&&i==-1&&d==-1)
break;
s++;
n=(5544*p+14421*e+1288*i+21252-d)%(23*28*33);
if (n<=0) printf("Case %d: the next triple peak occurs in %d days.\n",s,21252-d);
else
printf("Case %d: the next triple peak occurs in %d days.\n",s,n);
}
return 0;
}
第一次多加了对p==0&&e==0&&i==0&&d==0的处理WA
第二次多加了对p==365&&e==365&&i==365&&d==365的处理WA
其实p,e,i和d的取值没有直接关联,而是讨论求得的n是否<=0。(此处还有些疑问,明明在n中已经加过21252了。那n还有<0的可能么?
所以就把n〈=0改成n==0试了下,过了。 可能是只有n<=0中只有n==0的情况把。
POJ1006同余定理