poj1061 青蛙的约会 扩展欧几里得

中文题

思路: 扩展欧几里得

扩展欧几里得

  • 给定整数a 和 b, 且满足 a*x1 + b*y1 = gcd(a, b), 求解x, y.
  • 当 b == 0 的时候, gcd(a, b) = a. 此时x = 1, y = 0.
  • 当a*b != 0的时候, 推理: 根据欧几里得可知, gcd(a, b) = gcd(b, a%b). 那么 a*x1 + b*y1 = b*x2 + a%b*y2

   化解上式得到 b*x2 + (a - (a/b)*b)*y2 = a*y2 + b*x2 - (a/b)*b*y2.

   而根据恒等定理可知: x1 = y2, y1 = x2 - a/b*y2 ,由此我们可以知道求得x1, x2 的结果是基于x2, y2 而得到的, 因此我们只需要不断的递归下去,即:

   gcd(a, b) =gcd(b, a%b)=gcd(a%b, b%(a%b)) 直到b == 0 返回x2, y2 的结果, 通过恒等定理求得x1, y1.

  • 对于方程a*x1 + b*y1 = c , 我们可以根据上面求得的方程 a*x1 + b*y1 = gcd(a, b)转换得到(设d = gcd(a, b)).
  • a*x1 + b*y1 = d 转换得到: a(x1*c/d) + b(y1*c/d) = c.
  • 因此方程的解为x = x1*c/d, y = y1*c/d.

构建方程:

 (x + m* t) % L = (y + n*t) % L

转换得到:

x + m*t = y + n*t + w*L;
 (n - m)*t + w*L = x - y;
 即扩展欧几里得:a*x + b*t = c

 1 #include <iostream>
 2 using namespace std;
 3 
 4 long long extended_gcd(long long a, long long b, long long  &x, long long  &y)
 5 {
 6     long long ret , tmp;
 7     if (b == 0)
 8     {
 9         x = 1, y = 0;
10         return a;
11     }
12     ret = extended_gcd(b, a%b, x, y);
13     tmp = x;
14     x = y;
15     y = tmp - a /b *y;
16     return ret;
17 }
18 
19 int main()
20 {
21     long long x, y, d, X, Y, n, m, L;
22     /*
23     x + m*t = y + n*t + w*L;
24     (n - m)*t + w*L = x - y; 
25     扩展欧几里得:a*x + b*t = b
26     */
27     while (cin>>x>>y>>m>>n>>L)
28     {
29         d = extended_gcd(n-m, L, X, Y);
30         if ((x - y) % d != 0)
31             cout<<"Impossible"<<endl;
32         else
33             cout<<((x - y) / d * X % L + L) % L<<endl;
34     }
35 
36     
37 }
View Code

 

转载于:https://www.cnblogs.com/lv-2012/archive/2013/06/14/3135840.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值