📌  相关文章
📜  重新排列数组以获得前缀GCD串联的最大可能值

📅  最后修改于: 2021-05-17 21:40:27             🧑  作者: Mango

给定由N个正整数组成的数组arr [] ,任务是重新排列数组元素,以使每个索引i的数组arr []的元素的GCD从索引0i串联而形成的数量是最大可能的。 。

例子:

方法:一个数字的GCD就是数字本身,因此X的第一个数字,即X [0]将始终等于arr [0] 。因此,为了确保X在所有可获得的数中最大, arr [0]需要最大。然后,通过跟踪已经布置的arr []最长前缀的GCD来查找要放置在该前缀之后的连续元素的值。请按照以下步骤解决以上问题:

  1. 数组的最大元素被设置为第一个元素,因此第一个前缀正确地排列在数组arr []中。
  2. 现在找到与前缀最后一个元素arr [1]连续的元素。
  3. 在这里 最长前缀(例如G )的GCD等于arr [0] ,因此遍历其余数组以找到G值最大的元素。
  4. 现在,交换元件ARR [1]给出最大GCD与值G的元素,更新G的值到该最大GCD获得即,G = GCD(G,ARR [1])。
  5. 现在最长的固定前缀变为arr [0]arr [1] ,继续此过程以找到arr [2]arr [3] ,…, arr [N – 1] ,以获得所需的数组。
  6. 完成上述步骤后,打印重新排列的数组。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find the maximum number
// obtainable from prefix GCDs
void prefixGCD(int arr[], int N)
{
    // Stores the GCD of the
    // longest prefix
    int gcc;
 
    // Sort the array
    sort(arr, arr + N);
 
    // Reverse the array
    reverse(arr, arr + N);
 
    // GCD of a[0] is a[0]
    gcc = arr[0];
    int start = 0;
 
    // Iterate to place the arr[start + 1]
    // element at it's correct position
    while (start < N - 1) {
 
        int g = 0, s1;
 
        for (int i = start + 1; i < N; i++) {
 
            // Find the element with
            // maximum GCD
            int gc = __gcd(gcc, arr[i]);
 
            // Update the value of g
            if (gc > g) {
                g = gc;
                s1 = i;
            }
        }
 
        // Update GCD of prefix
        gcc = g;
 
        // Place arr[s1] to it's
        // correct position
        swap(arr[s1], arr[start + 1]);
 
        // Increment start for the
        // remaining elements
        start++;
    }
 
    // Print the rearranged array
    for (int i = 0; i < N; i++) {
        cout << arr[i] << " ";
    }
}
 
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 1, 2, 3, 4 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    prefixGCD(arr, N);
 
    return 0;
}


Java
//Java program for
// the above approach
import java.util.*;
class GFG{
 
//Function to find the maximum number
//obtainable from prefix GCDs
static void prefixGCD(int arr[], int N)
{
  // Stores the GCD of the
  // longest prefix
  int gcc;
 
  // Sort the array
  Arrays.sort(arr);
 
  // Reverse the array
  arr = reverse(arr);
 
  // GCD of a[0] is a[0]
  gcc = arr[0];
  int start = 0;
 
  // Iterate to place
  // the arr[start + 1]
  // element at it's
  // correct position
  while (start < N - 1)
  {
    int g = 0, s1 = 0;
 
    for (int i = start + 1; i < N; i++)
    {
      // Find the element with
      // maximum GCD
      int gc = __gcd(gcc, arr[i]);
 
      // Update the value of g
      if (gc > g)
      {
        g = gc;
        s1 = i;
      }
    }
 
    // Update GCD of prefix
    gcc = g;
 
    // Place arr[s1] to it's
    // correct position
    arr = swap(arr, s1, start + 1);
 
    // Increment start for the
    // remaining elements
    start++;
  }
 
  // Print the rearranged array
  for (int i = 0; i < N; i++)
  {
    System.out.print(arr[i] + " ");
  }
}
   
static int __gcd(int a, int b) 
{ 
  return b == 0 ? a : __gcd(b, a % b);    
}
 
static int[] reverse(int a[])
{
  int i, n = a.length, t;
  for (i = 0; i < n / 2; i++)
  {
    t = a[i];
    a[i] = a[n - i - 1];
    a[n - i - 1] = t;
  }
  return a;
}
 
static int[] swap(int []arr,
                  int i, int j)
{
  int temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
  return arr;
}
     
//Driver Code
public static void main(String[] args)
{
  // Given array arr[]
  int arr[] = {1, 2, 3, 4};
 
  int N = arr.length;
 
  // Function Call
  prefixGCD(arr, N);
}
}
 
//This code is contributed by 29AjayKumar


Python3
# Python3 program for the above approach
from math import gcd
 
# Function to find the maximum number
# obtainable from prefix GCDs
def prefixGCD(arr, N):
     
    # Stores the GCD of the
    # longest prefix
    gcc = 0
 
    # Sort the array
    arr = sorted(arr)
 
    # Reverse the array
    arr = arr[::-1]
 
    # GCD of a[0] is a[0]
    gcc = arr[0]
    start = 0
 
    # Iterate to place the arr[start + 1]
    # element at it's correct position
    while (start < N - 1):
        g = 0
        s1 = 0
 
        for i in range(start + 1, N):
 
            # Find the element with
            # maximum GCD
            gc = gcd(gcc, arr[i])
 
            # Update the value of g
            if (gc > g):
                g = gc
                s1 = i
 
        # Update GCD of prefix
        gcc = g
 
        # Place arr[s1] to it's
        # correct position
        arr[s1], arr[start + 1] = arr[start + 1], arr[s1]
 
        # Increment start for the
        # remaining elements
        start += 1
 
    # Print the rearranged array
    for i in range(N):
        print(arr[i], end = " ")
 
# Driver Code
if __name__ == '__main__':
     
    # Given array arr[]
    arr = [ 1, 2, 3, 4 ]
 
    N = len(arr)
 
    # Function Call
    prefixGCD(arr, N)
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach 
using System;
class GFG{
 
// Function to find the maximum number
// obtainable from prefix GCDs
static void prefixGCD(int[] arr, int N)
{
     
  // Stores the GCD of the
  // longest prefix
  int gcc;
 
  // Sort the array
  Array.Sort(arr);
 
  // Reverse the array
  arr = reverse(arr);
 
  // GCD of a[0] is a[0]
  gcc = arr[0];
  int start = 0;
 
  // Iterate to place the
  // arr[start + 1] element
  // at it's correct position
  while (start < N - 1)
  {
    int g = 0, s1 = 0;
 
    for(int i = start + 1; i < N; i++)
    {
         
      // Find the element with
      // maximum GCD
      int gc = __gcd(gcc, arr[i]);
 
      // Update the value of g
      if (gc > g)
      {
        g = gc;
        s1 = i;
      }
    }
 
    // Update GCD of prefix
    gcc = g;
 
    // Place arr[s1] to it's
    // correct position
    arr = swap(arr, s1, start + 1);
 
    // Increment start for the
    // remaining elements
    start++;
  }
 
  // Print the rearranged array
  for(int i = 0; i < N; i++)
  {
    Console.Write(arr[i] + " ");
  }
}
   
static int __gcd(int a, int b) 
{ 
  return b == 0 ? a : __gcd(b, a % b);    
}
 
static int[] reverse(int[] a)
{
  int i, n = a.Length, t;
   
  for(i = 0; i < n / 2; i++)
  {
    t = a[i];
    a[i] = a[n - i - 1];
    a[n - i - 1] = t;
  }
  return a;
}
 
static int[] swap(int []arr, int i,
                             int j)
{
  int temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
  return arr;
}
     
//Driver Code
public static void Main()
{
     
  // Given array arr[]
  int[] arr = { 1, 2, 3, 4 };
 
  int N = arr.Length;
 
  // Function call
  prefixGCD(arr, N);
}
}
 
// This code is contributed by sanjoy_62


输出:
4 2 3 1






时间复杂度: O(N 2 )
辅助空间: O(1)