📜  与来自两个阵列的最大GCD配对

📅  最后修改于: 2021-04-24 14:28:26             🧑  作者: Mango

给定两个由n个整数组成的数组,其中array的值较小(值不能超过一个很小的数字,例如100)。找到最大gcd的对(x,y)。 x和y不能为同一数组。如果多个对具有相同的gcd,则考虑具有最大总和的对。

例子:

Input : a[] = {3, 1, 4, 2, 8}
        b[] = {5, 2, 12, 8, 3}
Output : 8 8
Explanation: The maximum gcd is 8 which is 
of pair(8, 8).  

Input: a[] = {2, 3, 5}
       b[] = {7, 11, 13}
Output: 5 13
Explanation: Every pair has a gcd of 1.
The maximum sum pair with GCD 1 is (5, 13)

天真的方法是对两个阵列中的每个对进行迭代,并找出可能的最大gcd。

一种有效的方法(仅当元素较小时)是应用sieve属性,为此,我们需要预先计算以下内容。

  1. 一个cnt数组,用于标记数组元素的存在。
  2. 我们检查从1到N的所有数字,并检查每个数字的倍数是否存在,然后存储先前数字的最大值或当前存在的倍数。
  3. 对于另一个阵列,也重复步骤1和2。
  4. 最后,我们检查最大倍数(这是第一个数组和第二个数组中的公倍数)以获得最大GCD,并在的位置存储元素,首先存储数组的元素,然后存储第二个元素的b数组已存储,因此我们将其打印出来。

下面是上述方法的实现

C++
// CPP program to find maximum GCD pair
// from two arrays
#include 
using namespace std;
  
// Find the maximum GCD pair with maximum
// sum
void gcdMax(int a[], int b[], int n, int N)
{
    // array to keep a count of existing elements
    int cnt[N] = { 0 };
  
    // first[i] and second[i] are going to store
    // maximum multiples of i in a[] and b[]
    // respectively.
    int first[N] = { 0 }, second[N] = { 0 };
  
    // traverse through the first array to
    // mark the elements in cnt
    for (int i = 0; i < n; ++i)
        cnt[a[i]] = 1;
  
    // Find maximum multiple of every number
    // in first array
    for (int i = 1; i < N; ++i)
        for (int j = i; j < N; j += i)
            if (cnt[j])
                first[i] = max(first[i], j);
  
    // Find maximum multiple of every number
    // in second array
    // We re-initialise cnt[] and traverse
    // through the second array to mark the
    // elements in cnt
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < n; ++i)
        cnt[b[i]] = true;
    for (int i = 1; i < N; ++i)
        for (int j = i; j < N; j += i)
  
            // if the multiple is present in the
            // second array then store the  max
            // of number or the  pre-existing
            // element
            if (cnt[j])
                second[i] = max(second[i], j);
  
    // traverse for every elements and checks 
    // the maximum N that is present in both 
    // the arrays
    int i;
    for (i = N - 1; i >= 0; i--)
        if (first[i] && second[i])
            break;
  
    cout << "Maximum GCD pair with maximum "
            "sum is " << first[i] << " "
         << second[i] << endl;
}
  
// driver program to test the above function
int main()
{
    int a[] = { 3, 1, 4, 2, 8 };
    int b[] = { 5, 2, 12, 8, 3 };
    int n = sizeof(a) / sizeof(a[0]);
  
    // Maximum possible value of elements
    // in both arrays.
    int N = 20;
  
    gcdMax(a, b, n, N);
    return 0;
}


Java
// Java program to find maximum 
// GCD pair from two arrays
class GFG
{
      
// Find the maximum GCD
// pair with maximum sum
static void gcdMax(int[] a, int[] b, 
                   int n, int N)
{
    // array to keep a count 
    // of existing elements
    int[] cnt = new int[N];
  
    // first[i] and second[i] 
    // are going to store
    // maximum multiples of 
    // i in a[] and b[]
    // respectively.
    int[] first = new int[N];
    int[] second = new int[N];
  
    // traverse through the 
    // first array to mark 
    // the elements in cnt
    for (int i = 0; i < n; ++i)
        cnt[a[i]] = 1;
  
    // Find maximum multiple 
    // of every number in
    // first array
    for (int i = 1; i < N; ++i)
        for (int j = i; j < N; j += i)
            if (cnt[j] > 0)
                first[i] = Math.max(first[i], j);
  
    // Find maximum multiple 
    // of every number in second 
    // array. We re-initialise 
    // cnt[] and traverse through 
    // the second array to mark 
    // the elements in cnt
    cnt = new int[N];
    for (int i = 0; i < n; ++i)
        cnt[b[i]] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = i; j < N; j += i)
  
            // if the multiple is present 
            // in the second array then 
            // store the max of number or 
            // the pre-existing element
            if (cnt[j] > 0)
                second[i] = Math.max(second[i], j);
  
    // traverse for every 
    // elements and checks 
    // the maximum N that
    // is present in both 
    // the arrays
    int x;
    for (x = N - 1; x >= 0; x--)
        if (first[x] > 0 && 
            second[x] > 0)
            break;
  
    System.out.println(first[x] + " " + 
                            second[x]);
}
  
// Driver Code
public static void main(String[] args)
{
    int[] a = { 3, 1, 4, 2, 8 };
    int[] b = { 5, 2, 12, 8, 3 };
    int n = a.length;
  
    // Maximum possible 
    // value of elements
    // in both arrays.
    int N = 20;
  
    gcdMax(a, b, n, N);
}
}
  
// This code is contributed 
// by mits


Python3
# Python 3 program to find maximum GCD pair
# from two arrays
  
# Find the maximum GCD pair with maximum
# sum
def gcdMax(a, b, n, N):
  
    # array to keep a count of existing elements
    cnt = [0]*N
  
    # first[i] and second[i] are going to store
    # maximum multiples of i in a[] and b[]
    # respectively.
    first = [0]*N 
    second = [0]*N
  
    # traverse through the first array to
    # mark the elements in cnt
    for i in range(n):
        cnt[a[i]] = 1
  
    # Find maximum multiple of every number
    # in first array
    for i in range(1,N):
        for j in range(i,N,i):
            if (cnt[j]):
                first[i] = max(first[i], j)
  
    # Find maximum multiple of every number
    # in second array
    # We re-initialise cnt[] and traverse
    # through the second array to mark the
    # elements in cnt
    cnt = [0]*N
    for i in range(n):
        cnt[b[i]] = 1
    for i in range(1,N):
        for j in range(i,N,i):
  
            # if the multiple is present in the
            # second array then store the max
            # of number or the pre-existing
            # element
            if (cnt[j]>0):
                second[i] = max(second[i], j)
              
    # traverse for every elements and checks 
    # the maximum N that is present in both 
    # the arrays
      
    i = N-1
    while i>= 0:
        if (first[i]>0 and second[i]>0):
            break
        i -= 1
      
    print( str(first[i]) + " " + str(second[i]))
  
# driver program to test the above function
if __name__ == "__main__":
    a = [ 3, 1, 4, 2, 8 ]
    b = [ 5, 2, 12, 8, 3 ]
    n = len(a)
  
    # Maximum possible value of elements
    # in both arrays.
    N = 20
    gcdMax(a, b, n, N)
  
# this code is contributed by ChitraNayal


C#
// C# program to find 
// maximum GCD pair 
// from two arrays
using System;
  
class GFG
{
// Find the maximum GCD
// pair with maximum sum
static void gcdMax(int[] a, int[] b, 
                   int n, int N)
{
    // array to keep a count 
    // of existing elements
    int[] cnt = new int[N];
  
    // first[i] and second[i] 
    // are going to store
    // maximum multiples of 
    // i in a[] and b[]
    // respectively.
    int[] first = new int[N];
    int[] second = new int[N];
  
    // traverse through the 
    // first array to mark 
    // the elements in cnt
    for (int i = 0; i < n; ++i)
        cnt[a[i]] = 1;
  
    // Find maximum multiple 
    // of every number in
    // first array
    for (int i = 1; i < N; ++i)
        for (int j = i; j < N; j += i)
            if (cnt[j] > 0)
                first[i] = Math.Max(first[i], j);
  
    // Find maximum multiple 
    // of every number in second 
    // array. We re-initialise 
    // cnt[] and traverse through 
    // the second array to mark 
    // the elements in cnt
    cnt = new int[N];
    for (int i = 0; i < n; ++i)
        cnt[b[i]] = 1;
    for (int i = 1; i < N; ++i)
        for (int j = i; j < N; j += i)
  
            // if the multiple is present 
            // in the second array then 
            // store the max of number or 
            // the pre-existing element
            if (cnt[j] > 0)
                second[i] = Math.Max(second[i], j);
  
    // traverse for every 
    // elements and checks 
    // the maximum N that
    // is present in both 
    // the arrays
    int x;
    for (x = N - 1; x >= 0; x--)
        if (first[x] > 0 && 
            second[x] > 0)
            break;
  
    Console.WriteLine(first[x] + 
                      " " + second[x]);
}
  
// Driver Code
static int Main()
{
    int[] a = { 3, 1, 4, 2, 8 };
    int[] b = { 5, 2, 12, 8, 3 };
    int n = a.Length;
  
    // Maximum possible 
    // value of elements
    // in both arrays.
    int N = 20;
  
    gcdMax(a, b, n, N);
    return 0;
}
}
  
// This code is contributed 
// by mits


PHP
= 0; $x--)
        if ($first[$x] && $second[$x])
            break;
  
        echo $first[$x] . " " .
             $second[$x] . "\n";
}
  
// Driver code
$a = array(3, 1, 4, 2, 8);
$b = array(5, 2, 12, 8, 3);
$n = sizeof($a);
  
// Maximum possible value 
// of elements in both arrays.
$N = 20;
  
gcdMax($a, $b, $n, $N);
  
// This code is contributed 
// by mits
?>


输出 :

8 8

时间复杂度: O(N Log N + n)。请注意,N +(N / 2)+(N / 3)+….. + 1 = N logN。

辅助空间: O(N)