`
王宝林
  • 浏览: 14907 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

欧几里得算法、拓展欧几里得算法解青蛙约会问题

阅读更多

青蛙约会问题:

POJ_1061 写道
      两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
Input
输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。
Output
输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行"Impossible"
Sample Input
1 2 3 4 5
Sample Output
4

采用欧几里得算法和拓展欧几里得算法解决该问题,算法步骤如下:

1.问题可描述为:(m-n)*t+p*L=y-x,令a=m-n,b=y-x.

a*t+p*L=b

2.于是化为解决求a * x + b * y = n的整数解的问题。

 

  • 先计算Gcd(a,b),若n不能被Gcd(a,b)整除,则方程无整数解;否则,在方程两边同时除以Gcd(a,b),得到新的不定方程a' * x + b' * y = n',此时Gcd(a',b')=1;
  • 利用上面所说的欧几里德算法求出方程a' * x + b' * y = 1的一组整数解x0,y0,则n' * x0,n' * y0是方程a' * x + b' * y = n'的一组整数解;
  • 根据数论中的相关定理,可得方程a' * x + b' * y = n'的所有整数解为:

x = n' * x0 + b' * t

 

y = n' * y0 - a' * t(t为整数)

 

  • 上面的解也就是a * x + b * y = n 的全部整数解。

以下为欧几里得算法和拓展欧几里得算法的原理,引自木瓜的博客

欧几里得算法:

 

欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:

定理:gcd(a,b) = gcd(b,a mod b)

证明:a可以表示成a = kb + r,则r = a mod b

假设d是a,b的一个公约数,则有d|a, d|b,而r = a - kb,因此d|r,因此d是(b,a mod b)的公约数;

假设d 是(b,a mod b)的公约数,则d | b , d |r ,但是a = kb +r,因此d也是(a,b)的公约数;

因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证

欧几里德算法就是根据这个原理来做的,其算法用C++语言描述为: 

 

int Gcd(int a, int b)
{
     if(b == 0)
          return a;
       return Gcd(b, a % b);
}

 

当然你也可以写成迭代形式:

 

int Gcd(int a, int b)
{
      while(b != 0)
      {
          int r = b;
      b = a % b;
        a = r;
      }
      return a;
}

拓展欧几里得算法

扩展欧几里德算法是用来在已知a, b求解一组x,y使得a*x+b*y=Gcd(a,b)(解一定存在,根据数论中的相关定理)。扩展欧几里德常用在求解模线性方程及方程组中。下面是一个使用C++的实现:

int exGcd(int a, int b, int &x, int &y)
{
     if(b == 0)
     {
          x = 1;
          y = 0;
          return a;
     }
     int r = exGcd(b, a % b, x, y);
     int t = x;
     x = y;
     y = t - a / b * y;
   return r;
}
 
分享到:
评论

相关推荐

    欧几里得算法的应用 欧几里得算法的应用 欧几里得算法的应用

    #### 拓展欧几里得算法:线性丢番图方程的解 拓展欧几里得算法是对基础欧几里得算法的扩展,用于解决一类特殊的线性丢番图方程,形式为\(ax + by = gcd(a, b)\)。当\(gcd(a, b) = 1\),即\(a\)和\(b\)互质时,该...

    使用扩展欧几里得算法求乘法逆元

    扩展欧几里得算法是欧几里得算法的一种扩展,不仅能够找到两个整数的最大公约数(GCD),还能同时计算出它们的贝祖等式解。贝祖等式是这样的形式:ax + by = gcd(a, b),其中x和y是求解的系数。当a和b互质时,即gcd...

    欧几里得算法及扩展的欧几里得算法的C++实现

    欧几里得算法,又称辗转相除法,是古希腊数学家欧几里得提出的一种求解最大公约数(Greatest Common Divisor, GCD)的方法。该算法基于一个基本事实:两个正整数a和b的GCD(假设a&gt;b),等于a除以b的余数c与b之间的...

    扩展欧几里得算法求逆元

    扩展欧几里得算法求逆元

    算法_用欧几里得算法求最大公因数_

    欧几里得算法,也称为辗转相除法,是解决这一问题的经典算法,其历史可以追溯到古希腊数学家欧几里得的著作《几何原本》。本篇将详细介绍欧几里得算法及其扩展形式,并展示如何在编程中实现。 欧几里得算法基于以下...

    欧几里得算法的应用 (WC2009)

    ### 欧几里得算法的应用 (WC2009) #### 1. 欧几里得算法 ...无论是基础的辗转相除法还是更复杂的拓展欧几里得算法,亦或是看似与数论无关的问题,都能从欧几里得算法中汲取灵感,找到解决问题的新途径。

    扩展欧几里得算法的matlab程序(求多项式的乘法逆元)

    在数学和计算机科学中,扩展欧几里得算法是一种用于计算最大公约数(GCD)的有效方法,同时还可以找到两个整数的线性同余方程的解。在这个场景下,我们关注的是如何使用扩展欧几里得算法来求解多项式的乘法逆元,...

    java语言实现的欧几里得算法,求最大公约数,以及满足(a,b)=x*a+y*b的x和y

    java语言实现的欧几里得算法,求最大公约数,以及满足(a,b)=x*a+y*b的x和y

    c语言实现扩展的欧几里得算法

    在编程中,理解并能够正确实现扩展的欧几里得算法是至关重要的,因为它在许多加密算法(如RSA)和数学问题中都有应用。理解其工作原理并能熟练运用,不仅可以提高编程能力,也能加深对数论概念的理解。

    扩展欧几里得算法-python版

    当a,b,且a互质时,计算ax+by=1的值, 是计算RSA密钥的基本步骤之一。

    东南大学密码学实验——扩展欧几里得算法

    扩展欧几里得算法是基于欧几里得算法的一种扩展,它不仅能够求出两个整数的最大公约数(Greatest Common Divisor, GCD),还能得到两个整数的最大公约数下的贝祖等式解。这个等式通常写作:ax + by = gcd(a, b),...

    欧几里得算法总结

    ### 欧几里得算法总结 #### 一、课程概览 本章节主要介绍了欧几里得算法的相关概念和应用。欧几里得算法是一种用于计算两个整数最大公约数(Greatest Common Divisor, GCD)的经典算法。该算法在密码学等多个领域...

    欧几里得算法的简单概述

    ### 欧几里得算法的简单概述 #### 概述 欧几里得算法(Euclidean Algorithm),也称为辗转相除法,是一种用于计算两个正整数最大公约数(Greatest Common Divisor, GCD)的经典算法。该算法最早出现在古希腊数学家...

    PHP类欧几里得以及拓展欧几里得算法

    用PHP实现欧几里得和拓展欧几里得计算的程序。

    乘法逆元(扩展欧几里得算法)

    扩展欧几里得算法是对基本的欧几里得算法的一种扩展,它可以用来求解两个整数的最大公约数,并且还可以找到这两个整数的线性组合等于最大公约数的解。具体而言,如果两个整数 \( a \) 和 \( b \) 的最大公约数为 \( ...

    扩展的欧几里得算法(实现求乘法逆元)

    欧几里得是数论中的一个最初步的概念,它用来判断两个数的最大公因子,扩展的欧几里得能够进一步实现在两个数互素情况下的乘法可逆元。求可逆元是一些算法的基础。

    JAVA的欧几里得算法 最大公倍数

    通过欧几里得算法求到最大公约数,然后得出最小公倍数

    35扩展欧几里得算法1

    在 UVa 12169 Disgruntled Judge 题目中,我们可以使用扩展欧几里得算法来解决该问题。首先,我们可以枚举 a 的值,然后根据 x1 和 x3 计算出 b 的值。由于 a 和 b 都在 10000 以内,我们可以使用枚举的方法来枚举 a...

    欧几里得算法最大公约数1

    欧几里得算法最大公约数1 欧几里得算法是一种常用的算法,用来计算两个整数之间的最大公约数(Greatest Common Divisor,GCD)。该算法的时间复杂度为 O(log n),是一种高效的算法。 在上述代码中,我们可以看到,...

    扩展欧几里得算法C++程序

    本算法实现了用扩展欧几里得的方法求最大公因子和模逆元的方法,可以直接运行。

Global site tag (gtag.js) - Google Analytics