查找具有给定GCD值的数字

Finding numbers with given GCD values

本文关键字:数字 GCD 查找      更新时间:2023-10-16

我正在查看欧几里得算法来查找数字的GCD。现在,它可以用来求两个给定数的GCD。但是,如果给定一个数字与多个其他数字的GCD,例如,第一个数字与其他3个数字(包括其本身)的GCD,即

已知:a与a的GCD, a与b的GCD, a与c的GCD, a与d的GCD。其他数字也一样,即b与a的GCD, b与b的GCD, .....

那么,我怎样才能找到单独的号码呢?我知道GCD(a,a) = a本身,但这里的问题是,给定的单个GCD是随机顺序的,因此,我不知道哪个输入数字是哪两个数字的GCD。在这种情况下,我如何找到单个号码?

这是我的GCD代码:

int gcd(int a,int b)
{
   if(b==0)
   {
       return a;
   }
   return gcd(b,a%b);
}
示例:假设给定的输入是
3 1 3 1 4 2 2 3 6
3 //(total numbers we have to find in original array)

则输出应为,3 4 6。因为如果您两两计算每个数字的GCD(总共9对,因此9个数字作为输入),那么我们将得到如上所示的输出。

Explanation: 3 -> GCD of (3,3)
1 -> GCD of (3,4)
3 -> GCD of (3,6)
1 -> GCD of (4,3)
4 -> GCD of (4,4)
2 -> GCD of (4,6)
6 -> GCD of (6,6)
3 -> GCD of (6,3)
2 -> GCD of (6,4)

因此,我必须找到GCD作为输入的数字。因此,(3,4,6)就是这些数字。

我认为你可以通过以下步骤做到这一点:

  1. 查找并删除最大数字,这是原始数字之一
  2. 计算步骤1中刚刚找到的数字的gcd,其中包含步骤1中先前找到的所有数字。
  3. 从gcd的输入数组中删除这些计算的gcd(严格地说,删除每个gcd的2个副本)
  4. 重复,直到找到所有的数字

关键是,只有在步骤1中找到的最大数字x不是原始数字之一时,这才会出错。然而,只有当x是另外两个数的乘积时才会发生这种情况。这些数字必须至少和x一样大,但是在步骤3中已经删除了所有这些gcd。因此x总是原始数之一。

如果输入的第二行是1,那么输入的第一行将只有一个数字,并且由于您观察到gcd(a, a) = a, a的值将是输入的第一行上的任何值。

如果第二行输入的值大于1,则可以使用以下观察结果减少问题。给定正整数ab,我们知道gcd(a, b) <= a = gcd(a, a)gcd(a, b) <= b = gcd(b, b)总是成立的。因此,我们可以得出结论,输入的第一行上最大的两个数字一定都是基本数字集的一部分。最大的两个数字可能是相等的,但在你的例子中,它们是46,它们是不相等的。

如果有两个以上的数要找,我们称最大的两个为ab。既然我们现在知道ab的值,我们可以计算gcd(a, b),并将该值的两次出现从考虑中移除,作为输入数字之一。我们删除了两次出现,因为gcd(a, b) = gcd(b, a)都在输入数字列表中。然后使用类似的逻辑,我们得出结论,在a, b, gcd(a, b)gcd(b, a)被删除后剩下的最大的数字一定是输入数字之一。

清洗,漂洗,重复。

这其实很简单:

  • 计算每个不同的数字在数组中出现的次数
  • 如果该计数为奇数,则它是您的集合中的一个数字
  • 如果该计数为偶数,则该数字不在您的集合中。

之所以有效是因为当x != y时,gcd(x,y) = gcd(y,x)并且该数字将在数组中出现两次。只有来自gcd(x,x)的值才会在数组中出现一次,导致该特定值为奇数。

正如我们在这里看到的,对于每个带有其他数字的数字,计算一个GCD并将其添加到现有列表中,就像这样,最终我们将为原始n个数字获得n*n个总数。因此,同样的方法可以反向用于查找原始数字

  1. 按降序排序。
  2. 收集最上面的n^(0.5)个数字,这将是我们的答案。

对于您的示例

3 1 3 1 4 2 2 3 6

Sorted = 6 4 3 3 3 2 2 1 1

n = 9

n^(0.5) = 3

选择前3个数字6、4、3。这就是我们的答案