原题
题目分析
由题可知要求解一下方程组
(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 }