青蛙约会问题:
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...
欧几里得算法,又称辗转相除法,是古希腊数学家欧几里得提出的一种求解最大公约数(Greatest Common Divisor, GCD)的方法。该算法基于一个基本事实:两个正整数a和b的GCD(假设a>b),等于a除以b的余数c与b之间的...
扩展欧几里得算法求逆元
欧几里得算法,也称为辗转相除法,是解决这一问题的经典算法,其历史可以追溯到古希腊数学家欧几里得的著作《几何原本》。本篇将详细介绍欧几里得算法及其扩展形式,并展示如何在编程中实现。 欧几里得算法基于以下...
### 欧几里得算法的应用 (WC2009) #### 1. 欧几里得算法 ...无论是基础的辗转相除法还是更复杂的拓展欧几里得算法,亦或是看似与数论无关的问题,都能从欧几里得算法中汲取灵感,找到解决问题的新途径。
在数学和计算机科学中,扩展欧几里得算法是一种用于计算最大公约数(GCD)的有效方法,同时还可以找到两个整数的线性同余方程的解。在这个场景下,我们关注的是如何使用扩展欧几里得算法来求解多项式的乘法逆元,...
java语言实现的欧几里得算法,求最大公约数,以及满足(a,b)=x*a+y*b的x和y
在编程中,理解并能够正确实现扩展的欧几里得算法是至关重要的,因为它在许多加密算法(如RSA)和数学问题中都有应用。理解其工作原理并能熟练运用,不仅可以提高编程能力,也能加深对数论概念的理解。
当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实现欧几里得和拓展欧几里得计算的程序。
扩展欧几里得算法是对基本的欧几里得算法的一种扩展,它可以用来求解两个整数的最大公约数,并且还可以找到这两个整数的线性组合等于最大公约数的解。具体而言,如果两个整数 \( a \) 和 \( b \) 的最大公约数为 \( ...
欧几里得是数论中的一个最初步的概念,它用来判断两个数的最大公因子,扩展的欧几里得能够进一步实现在两个数互素情况下的乘法可逆元。求可逆元是一些算法的基础。
通过欧几里得算法求到最大公约数,然后得出最小公倍数
在 UVa 12169 Disgruntled Judge 题目中,我们可以使用扩展欧几里得算法来解决该问题。首先,我们可以枚举 a 的值,然后根据 x1 和 x3 计算出 b 的值。由于 a 和 b 都在 10000 以内,我们可以使用枚举的方法来枚举 a...
欧几里得算法最大公约数1 欧几里得算法是一种常用的算法,用来计算两个整数之间的最大公约数(Greatest Common Divisor,GCD)。该算法的时间复杂度为 O(log n),是一种高效的算法。 在上述代码中,我们可以看到,...
本算法实现了用扩展欧几里得的方法求最大公因子和模逆元的方法,可以直接运行。