给定两个由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属性,为此,我们需要预先计算以下内容。
- 一个cnt数组,用于标记数组元素的存在。
- 我们检查从1到N的所有数字,并检查每个数字的倍数是否存在,然后存储先前数字的最大值或当前存在的倍数。
- 对于另一个阵列,也重复步骤1和2。
- 最后,我们检查最大倍数(这是第一个数组和第二个数组中的公倍数)以获得最大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)