POJ1006-中国剩余定理

  题目大意是:体力、情感和智力三个生理周期分别为23,28和33天,已知它们分别在p,q,e天到达顶峰,给出当前日期,求多少天后三个生理周期同时到达顶峰。

 1.第一次做时不知道剩余定理,就用的暴搜,考虑的各种不完善,WA了n次。 

Problem: 1006   User: wjinkun
Memory: 388K   Time: 94MS
Language: GCC   Result: Accepted
 1 #include <stdio.h>
 2 
 3 //解这个方程:23x+p=28*y+e=33z+i;
 4 int main()
 5 {
 6     int physical,emotional,intellectual,date;
 7     int i,y,e_p,e_i,day;
 8     for(i=1;i;i++)
 9     {
10         scanf("%d%d%d%d",&physical,&emotional,&intellectual,&date);
11         if(physical==-1&&emotional==-1&&intellectual==-1)
12             break;
13         e_p=emotional-physical;
14         e_i=emotional-intellectual;
15         y=1;
16         while(1)
17         {
18             while((e_p+y*28)%23)
19                 y++;
20             if((28*y+e_i)%33==0)
21                 break;
22             else
23                 y++;
24         }
25         day=emotional+28*y-date;
26         if(day<=0)                       //开始没考虑这种情况
27             day+=21252;
28         else if(day-21252>0)
29             day-=21252;
30         printf("Case %d: the next triple peak occurs in %d days.\n",i,day);
31     }
32     return 0;
33 }

2.看了discuss才知道剩余定理,学习了一下:

一般地,中国剩余定理是指若有一些两两互质的整数 m_1, m_2, \ldots, m_n,则对任意的整数:a_1, a_2,...a_n,以下联立同余方程组对模 m_1 m_2 \cdots m_n 有公解:

\left\{ \begin{matrix} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \\ \vdots \qquad\qquad\qquad \\ x \equiv a_n \pmod {m_n} \end{matrix} \right.

   这个题目可表示为:day≡p (mod 23),day≡e (mod 28),day≡i (mod 33);现设n1≡p (mod 23),n2≡e (mod 28),n3≡i (mod 33),为了使day==n1+n2+n3,那么n2,n3必须是23的倍数,n1,n3必须是28的倍数,n1,n2必须是33的倍数。这样题目可化为

  • n1≡p (mod 23),n1≡0 (mod 28/33);
  • n2≡e (mod 28),n2≡0 (mod 23/33);
  • n3≡i (mod 33),n3≡0 (mod 23/28);

 这里先求n≡1 (mod 23),则n1=p*n.可以求出n1=p*5544,n2=e*14421,n3=i*1288;所以day=(n1+n2+n3)%21252.

Problem: 1006   User: wjinkun
Memory: 388K   Time: 63MS
Language: GCC   Result: Accepted

 

 1 #include <stdio.h>
 2 
 3 //中国剩余定理
 4 int main()
 5 {
 6     int physical,emotional,intellectual,date;
 7     int day,i;
 8     for(i=1;i;i++)
 9     {
10         scanf("%d%d%d%d",&physical,&emotional,&intellectual,&date);
11         if(physical==-1&&emotional==-1&&intellectual==-1)
12             break;
13         physical%=23;                        //减少运算量
14         emotional%=28;
15         intellectual%=33;
16         day=(physical*5544+emotional*14421+intellectual*1288)%21252-date;
17         if(day<=0)
18             day+=21252;
19         printf("Case %d: the next triple peak occurs in %d days.\n",i,day);
20     }
21     return 0;
22 }

实在不明白那些0MS的怎么做到的。。。。

posted on 2012-08-17 12:40  wjinkun  阅读(158)  评论(0编辑  收藏  举报

导航