POJ 1061 青蛙的约会 扩展欧几里得

来源:互联网 发布:淘宝网店费用 一年 编辑:程序博客网 时间:2024/06/07 10:07

题目链接

思路:

这个题目可以转化为:  

x + km=y + kn (% L)

k(m-n)=y - x (% L)

k(m-n) + t*L =  y -x    进而转化到扩展欧几里得.


ll exgcd(ll a,ll b,ll &x,ll &y)  {      if(b == 0)      {          x = 1;          y = 0;          return a;      }      ll ans = exgcd(b,a%b,x,y);      ll tmp = x;      x = y;      y = tmp - a/b * y;      return ans;  }  

上面这个代码求出的是 a*x+b*y = gcd(a,b)

如果 c%gcd(a,b)==0  ,就说明有解,

最小整数解为 b=b/gcd(a,b)   x=x*(c/gcd(a,b))   x=(x%b+b)%b

ll cal(ll a,ll b,ll c)  {      ll x,y;      ll gcd = exgcd(a,b,x,y);      if(c%gcd!=0) return -1;      x*=c/gcd;      b/=gcd;      if(b<0) b=-b;      ll ans = x % b;      if(ans <= 0)      ans += b;      return ans;  }  
#include <iostream>  #include <cstdio>  #include <cstring>  #include <cmath>  #include <vector>  #include <string>  #include <queue>  #include <stack>  #include <algorithm>    #define INF 0x7fffffff  #define EPS 1e-12  #define MOD 1000000007  #define PI 3.141592653579798  #define N 100000    using namespace std;    typedef long long ll;  typedef double DB;    ll exgcd(ll a,ll b,ll &x,ll &y)  {      if(b == 0)      {          x = 1;          y = 0;          return a;      }      ll ans = exgcd(b,a%b,x,y);      ll tmp = x;      x = y;      y = tmp - a/b * y;      return ans;  }    ll cal(ll a,ll b,ll c)  {      ll x,y;      ll gcd = exgcd(a,b,x,y);      if(c%gcd!=0) return -1;      x*=c/gcd;      b/=gcd;      if(b<0) b=-b;      ll ans = x % b;      if(ans <= 0)      ans += b;      return ans;  }    int main()  {      ll x,y,m,n,L;      while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L)!=EOF)      {          ll ans=cal(m-n,L,y-x);          if(ans==-1) printf("Impossible\n");          else printf("%lld\n",ans);      }      return 0;  }  



原创粉丝点击