首页 > 代码库 > 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同余定理