Biorhythms POJ 1006(中国剩余定理)

原题

题目链接

题目分析

由题可知要求解一下方程组

(x+d)≡p(mod23)

(x+d)≡e(mod28)

(x+d)≡i(mod33)

很明显23 28 33互质,因此这道题只需要用中国剩余定理的结论求出ans-x+d,最后ans-d之后用ans=(ans%lcm(23,28,33)+lcm(23,28,33))lcm(23,28,33)取一下最小正解即可,这里要注意一下,当ans是0的时候ans=lcm(23,28,33).

代码

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <utility>
 4 #include <cstdio>
 5 #include <cstdlib>
 6 #include <ctime>
 7 #include <cmath>
 8 #include <cstring>
 9 #include <string>
10 #include <vector>
11 #include <stack>
12 #include <queue>
13 #include <map>
14 #include <set>
15 
16 using namespace std;
17 typedef unsigned long long ULL;
18 typedef long long LL;
19 typedef long double LB;
20 const int INF_INT=0x3f3f3f3f;
21 const LL INF_LL=0x3f3f3f3f3f3f3f3f;
22 
23 LL n=3;
24 int a[3],m[3]={23,28,33};
25 
26 LL exgcd(LL a,LL b,LL &x,LL &y)
27 {
28     if(!b)
29     {
30         x=1,y=0;
31         return a;
32     }
33     LL g=exgcd(b,a%b,y,x); 
34     y-=a/b*x; 
35     return g;
36 }
37 
38 LL solve(int d)
39 {
40     LL M=1,ans=0,x,y;
41     for(int i=0;i<n;i++) M*=m[i],a[i]%=m[i];
42     for(int i=0;i<n;i++)
43     {
44         LL t=M/m[i];
45         exgcd(t,m[i],x,y);
46         ans+=a[i]*t*x;
47     }
48     ans-=d;
49     ans=((ans%M)+M)%M;
50     if(!ans) ans+=M;
51     return ans;
52 }
53 
54 int main()
55 {
56 //    freopen("std.in","r",stdin);
57 //    freopen("std.out","w",stdout);
58     int d,cnt=1;
59     while(~scanf("%d %d %d %d",&a[0],&a[1],&a[2],&d)&&(a[0]!=-1||a[1]!=-1||a[2]!=-1||d!=-1))
60         printf("Case %d: the next triple peak occurs in %lld days.\n",cnt++,solve(d));
61     return 0;
62 }

 

posted @ 2019-08-31 08:56  VBL  阅读(139)  评论(0编辑  收藏  举报