问题表明我们需要找到给定范围内的 GCD。我们将得到两个正整数 x 和 y 以及两个整数 p 和 q,其范围为 [p,q]。我们需要找出落在 [p,q] 范围内的数字 x 和 y 的 GCD(最大公约数)。 GCD,在数学中被称为最大公约数,是两个给定正整数相除的最大正整数。给定的整数不得为零。对于任意两个正整数 x 和 y,它表示为 gcd(x,y)。
例如,我们有两个正整数 6 和 9。最大公约数 gcd(6,9) 将为 3,因为它是除以这两个数字的最大数。
但是在这个问题中,我们需要找到两个给定的在指定范围内的正整数的最大公约数。让我们通过例子来理解这个问题。我们将得到 4 个数字作为输入 x 和 y 来查找这些数字的 gcd 和两个指示 gcd 范围的数字,即 [p,q]。
输入:x=8、y=12、p=1、q=3
输出:2
解释 - 由于给定的两个数字 x 和 y 的最大公约数是 4。但是 4 不在范围 [1,3] 之内。 [1,3] 范围内的最大公约数是 2,这是我们所需的输出。
输入:x=17、y=15、a=5、b=10
输出:-1
解释 - 数字 17 和 15 的最大公约数是 1。因为 1 不在给定范围 [5,10] 内。当给定范围内没有公约数时,我们需要打印 -1 作为输出。
算法
我们用来解决问题的算法非常简单并且与数学相关。首先,我们将找到数字 x 和 y 的 gcd(最大公约数)。在 C++ 中,有一个名为 gcd() 的内置函数,它返回数字的最大公约数作为输出。
语法
int divisor=gcd(x,y);
登录后复制
我们还可以使用欧几里得算法的有效方法来查找两个数字的 gcd。两者同时工作,时间复杂度为 O(log(min(x,y))。
现在,我们可以使用简单的算术定律得出结论:除以两个数字的 gcd 的数字也将除以这两个数字本身。因此,在 for 循环中从 i=1 迭代到 sqrt(gcd(x,y)) 将帮助我们获得该数字的所有公约数。
然后,检查每个 i 直到 sqrt(gcd(x,y)) i 是否整除 gcd(x,y)。如果 i 除以 gcd(x,y),那么我们可以说 gcd(x,y)/i 也将是 gcd 的除数,从而得出结论,它也是数字 x 和 y 的公约数。
让我们通过一个例子来理解这个概念。假设 x 和 y 分别为 32 和 48。gcd(18,27) 为 16。所以在这种情况下,我们将从 i=1 迭代到 i
注意 - 如果数字 n 除以任意数字 x 得到 y,可以表示为 $frac{n}{x}:=:y$ 那么 y 将将 n 除以 x $(x:times:y:=:n)$。
该算法可能是解决该问题的最有效方法。在遵循这个算法的同时,我们将不断检查公约数是否在 [a,b] 范围内。如果不正确,我们将使用 max() 函数不断更新变量中的除数,以获得范围内的最大公约数。
max() 函数的语法
int m = max(a,b);
登录后复制
它返回 a 和 b 的最大值。
方法
以下是我们将遵循的方法 -
-
初始化一个函数来计算给定范围内的最大公约数。
-
计算两个给定正数 x 和 y 的 gcd。
-
初始化变量名称 ans = -1。
-
在 for 循环中从 i=1 迭代到 i
-
如果 (gcd(x,y)%i)=0,检查 i 是否在 [a,b] 范围内,以及是否使用 max() 函数将其存储在 ans 中,以便我们得到最大公约数位于该范围内。
-
同时检查 gcd/i 是否在范围内,如果在范围内,则再次使用 max() 函数更新 ans 的值。
-
完成 for 循环中的所有迭代后返回 ans。
示例
该方法在 C++ 中的实现 -
#include
#include
using namespace std;
// to calculate gcd of two numbers using Euclidean algorithm
int gcd(int a, int b){
if(a == 0)
return b;
return gcd(b % a, a);
}
//function to calculate greatest common divisor in the given range [a,b]
int build(int x, int y, int a, int b) {
//using C++ inbuilt library to calculate gcd of given numbers
int z = gcd(x, y); //we can use euclidean algorithm too as an alternative
int ans = -1; //storing -1 for the case when no common divisor lies in the range
for(int i = 1; i= a && i = a && (z / i)