poj 1061 青蛙的约会

题目链接:http://poj.org/problem?id=1061        

        对于方程 a*x+b*y=n;有整数解得充分必要条件是(n %gcd(a,b)==0).这个定理这里就不证明了,数论书上都有。

 

       所以方程 a*x+b*y=n;我们可以先用扩展欧几里德算法求出一组x0,y0。也就是a*x0+b*y0=gcd(a,b);然后两边同时除以gcd(a,b),再乘以n。这样就得到了方程 a*x0*n/gcd(a,b)+b*y0*n/gcd(a,b)=n;我们也就找到了方程的一个解。即x=x0*n/gcd(a,b) ;y=y0*n/gcd(a,b).

 

     还有一个定理:若gcd(a,b)=1,且x0,y0为a*x+b*y=n的一组解,则该方程的任一解可表示为:x=x0+b*t,y=y0-a*t;且对任一整数t,皆成立。(这个证明比较简单,就不写了)

 

     这样我们就可以求出方程的所有解了,但实际问题中,我们往往被要求去求最小整数解,所以我们就可以将一个特解x,t=b/gcd(a,b),x=(x%t+t)%t;就可以了。x就是所求的最小整数解。

 

 

本题的方程可以化为(m-n)*t-k*L=itv,其中t,k为未知数,t就是本题所求结果。itv是刚开始他们之间的距离差。

 

View Code
 1 #include <iostream>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <cmath>
5 using namespace std;
6 typedef long long LL;
7 LL Ex_Eulid(LL a, LL b, LL &x, LL &y) //扩展欧几里德
8 {
9 if(b==0){x=1,y=0;return a;}
10 else
11 {
12 LL tx, ty, temp;
13 temp = Ex_Eulid(b, a%b, tx, ty);
14 x = ty, y = tx - (a / b) * ty;
15 return temp;
16 }
17 }
18 int main()
19 {
20 LL x,y,m,n,L,N,itv,spd,X,Y,gcd;
21 while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L)!=EOF)
22 {
23 if((m-n)<0) spd=-(m-n);
24 else spd = (m-n);
25
26 itv = (m>n)?((x>y)?(L-x+y):(y-x)):((x>y)?(x-y):(L-y+x)); //四种情况
27 /************************************************************************/
28 /* 本题方程式为:(m-n)*t-k*L=itv; */
29 /************************************************************************/
30 gcd = Ex_Eulid(spd,L,X,Y);
31 if(itv%gcd==0)
32 {
33 N = X*itv/gcd;
34 L /= gcd;
35 N = (L+N%L)%L;
36 printf("%lld\n",N); //N最小整数解
37 }
38 else printf("Impossible\n");
39 }
40 return 0;
41 }


posted @ 2012-02-24 15:58  我们一直在努力  阅读(194)  评论(0编辑  收藏  举报