Biorhythms HDU - 1370 (中国剩余定理)
孙子定理:
当前存在三个式子,t%3=2,t%5=3,t%7=2.然后让你求出t的值的一个通解。
具体过程:选取3和5的一个公倍数t1能够使得这个公倍数t1%7==1,然后选取3和7的一个公倍数t2使得这个公倍数t2%5==1,然后再选取5和7的一个公倍数t3使得这个公倍数t3%3==1,求出来
t1==15,t2==21,t3==70,然后最终的答案就是(15*3+21*3+70*2)+105*n.这里的105指的是3 5 7 的最小公倍数,为什么这样做?既然是有余数,那么就把这个余数搞没了就可以了。
附上李永乐老师的视频链接:https://www.bilibili.com/video/av25823277?from=search&seid=13476544282891947834
题目链接:https://cn.vjudge.net/problem/HDU-1370
题目大意:给你三个式子,让你求出满足题目条件的解。
(n-d)%23=p,(n-d)%28=e,(n-d)%33=i。给你d,p,e,i,让你求出n的值,其实把(n-d)看成一个整体,求出来之后再减去d就能求出n了。
中国剩余定理模板也存一下。
m数组是被除数,下标从0开始 m[0]=23,m[1]=28,m[2]=33.
b数组是等号右边的数,下标从0开始,b[0]=p,b[1]=e,b[2]=i。
然后求出的答案是(n-d)的值。
AC代码:
1 #include<iostream> 2 #include<stack> 3 #include<cstring> 4 #include<iomanip> 5 #include<stdio.h> 6 #include<algorithm> 7 #include<cmath> 8 #include<queue> 9 using namespace std; 10 # define ll long long 11 # define inf 1ll<<60 12 const int mod = 21252; 13 const int maxn = 1e3+100; 14 int exgcd(int a,int b,int &x,int &y){ 15 int d=a; 16 if(b!=0){ 17 d=exgcd(b,a%b,y,x); 18 y-=(a/b)*x; 19 } 20 else { 21 x=1; 22 y=0; 23 } 24 return d; 25 } 26 int china(int m0[],int b[]){ 27 int x,y,n,m=1,a=0; 28 for(int j=0;j<3;j++){ 29 m=m*m0[j]; 30 } 31 for(int j=0;j<3;j++){ 32 n=m/m0[j]; 33 exgcd(n,m0[j],x,y); 34 a=a+n*b[j]*x; 35 } 36 return a%m; 37 } 38 int main(){ 39 int T; 40 int b[15]; 41 int p,e,i,d; 42 int Case=0; 43 scanf("%d",&T); 44 while(~scanf("%d%d%d%d",&p,&e,&i,&d)){ 45 if(p==-1&&e==-1&&i==-1&&d==-1)break; 46 int m[3]={23,28,33}; 47 b[0]=p,b[1]=e,b[2]=i; 48 int sum=china(m,b)-d; 49 if(sum<=0)sum+=mod; 50 printf("Case %d: the next triple peak occurs in %d days.\n",++Case,sum); 51 } 52 return 0; 53 }