[POJ 1006] 生理周期
Description
Input
当p = e = i = d = -1时,输入数据结束。
Output
采用以下格式:
Case 1: the next triple peak occurs in 1234 days.
注意:即使结果是1天,也使用复数形式“days”。
Solution
愉快的推一发公式之后我们可以得到以下三个同余方程
$$x \equiv p \quad (mod\;23)$$
$$x \equiv e \quad (mod\;28)$$
$$x \equiv i \quad (mod\;33)$$
中国剩余定理的板子诶
直接 CRT 的板子敲上去然后判一下如果小于 d 的话就一直加余数(23*28*33)直到大于等于 d。
Code
1 #include<cstdio> 2 #define int long long 3 4 int T; 5 int d; 6 int r[5],a[5]; 7 int M=23*28*33; 8 9 int exgcd(int a,int b,int &x,int &y){ 10 if(!b){ 11 x=1;y=0; 12 return a; 13 } 14 int c=exgcd(b,a%b,x,y); 15 int t=x; 16 x=y; 17 y=t-a/b*y; 18 return c; 19 } 20 21 int inv(int a,int b){ 22 int x,y; 23 exgcd(a,b,x,y); 24 return (x%b+b)%b; 25 } 26 27 int CRT(){ 28 int ans=0; 29 for(int i=1;i<=3;i++) 30 (ans+=inv(M/a[i],a[i])*(M/a[i])*r[i])%=M; 31 while(ans<d) ans+=M; //注意不能是加d 32 if(ans==d) return 21252-d; 33 return ans-d; 34 } 35 36 signed main(){ 37 a[1]=23,a[2]=28,a[3]=33; 38 while(scanf("%lld%lld%lld%lld",&r[1],&r[2],&r[3],&d)){ 39 if(r[1]==-1) return 0; 40 T++; 41 printf("Case %lld: the next triple peak occurs in %lld days.\n",T,CRT()); 42 } 43 }