Biorhythms
POJ - 1006题意:
求解一元线性同余方程组。
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int maxn=1010; 5 int b[maxn],m[maxn]; 6 int n; 7 void exgcd(int a,int b,int &d,int &x,int &y){ 8 if(!b){d=a;x=1;y=0;} 9 else {exgcd(b,a%b,d,y,x);y-=x*(a/b);} 10 } 11 // 求解x%m=b 12 int solve(int* b,int* m,int n){ 13 int m1=m[0],b1=b[0];; 14 for(int i=1;i<n;i++){ 15 int m2=m[i],b2=b[i]; 16 int g,x,y; 17 exgcd(m1,m2,g,x,y); 18 int c=b2-b1; 19 if(c%g) return -1; //无解 20 x=x*(c/g); 21 int r=m2/g; 22 x=(x%r+r)%r; 23 b1+=m1*x; 24 m1*=m2/g; 25 b1%=m1; 26 } 27 return (b1%m1+m1-1)%m1+1; //返回正整数解 28 } 29 30 int main(){ 31 m[0]=23;m[1]=28;m[2]=33; 32 int kase=0; 33 while(scanf("%d",&b[0])){ 34 for(int i=1;i<3;i++) scanf("%d",&b[i]); 35 int x; 36 scanf("%d",&x); 37 if(x==-1) break; 38 int ans=solve(b,m,3); 39 ans=(ans-x+21251)%21252+1; 40 printf("Case %d: the next triple peak occurs in %d days. ",++kase,ans); 41 } 42 }
还可以用中国剩余定理~
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int maxn=1010; 5 int b[maxn],m[maxn]; 6 int n; 7 void exgcd(int a,int b,int &d,int &x,int &y){ 8 if(!b){d=a;x=1;y=0;} 9 else {exgcd(b,a%b,d,y,x);y-=x*(a/b);} 10 } 11 // 求解x%m[i]=b[i], 其中m互质 12 int china(int* b,int* m,int n){ 13 int M=1,ans=0; 14 for(int i=0;i<n;i++) M*=m[i]; 15 for(int i=0;i<n;i++){ 16 int N=M/m[i]; 17 int g,x,y; 18 exgcd(N,m[i],g,x,y); 19 ans=(ans+b[i]*N*x)%M; 20 } 21 return (ans+M)%M; 22 } 23 24 25 int main(){ 26 m[0]=23;m[1]=28;m[2]=33; 27 int kase=0; 28 while(scanf("%d",&b[0])){ 29 for(int i=1;i<3;i++) scanf("%d",&b[i]); 30 int x; 31 scanf("%d",&x); 32 if(x==-1) break; 33 int ans=china(b,m,3); 34 ans=(ans-x+21251)%21252+1; 35 printf("Case %d: the next triple peak occurs in %d days. ",++kase,ans); 36 } 37 }
求逆那些算一次就可以了