查找具有给定GCD值的数字

时间:2015-10-03 17:05:24

标签: c++ algorithm

我正在查看Eucledian算法以查找数字的GCD。现在,它可用于查找两个给定数字的GCD。但是,如果给我一个带有多个其他数字的单个数字的GCD,例如,第一个数字的GCD与其他3个数字(包括其自身),即

给出的是:a的GCD,a的GCD,a的c的gCD,a的g的gCD。 对于其他数字也是如此,即b的GCD与a,b与b,.....,

然后,我怎样才能找到个别数字?我知道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)是那些数字。

4 个答案:

答案 0 :(得分:3)

我认为你可以通过以下过程来做到这一点:

  1. 查找并删除最大数字,这是原始数字之一
  2. 计算步骤1中找到的数字的gcd,以及之前在步骤1中找到的所有数字。
  3. 从gcds的输入数组中删除这些计算的gcds中的每一个(严格地说,删除每个gcd的2个副本)
  4. 重复直到找到所有数字
  5. 关键是如果步骤1中找到的最大数字x不是原始数字之一,则只会出错。但是,只有当x是另外两个数字的gcd时才会发生这种情况。这些其他数字必须至少与x一样大,但是在步骤3中已经删除了所有这些gcds。因此x始终是原始数字之一。

答案 1 :(得分:1)

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

如果第二行输入的值大于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)都在输入数字列表中。然后使用类似的逻辑,我们得出结论,删除abgcd(a, b)gcd(b, a)后剩余的最大数字必须是输入数字之一。

洗涤,冲洗,重复。

答案 2 :(得分:1)

这实际上非常简单:

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

进行。

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

答案 3 :(得分:0)

正如我们在这里看到的那样,对于每个具有其他编号的数字,都会计算出一个GCD并将其添加到现有列表中,最终像这样,对于原始的n个数字,我们将得到n * n个总编号器。因此可以反向使用相同的方法来查找原始数字

  1. 按降序排列列表。
  2. 收集前n ^(0.5)个数字,这就是我们的答案。

以您为例

3 1 3 1 4 2 2 3 6

排序= 6 4 3 3 3 2 2 1 1

n = 9的值

n ^(0.5)= 3的值

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