📌  相关文章
📜  最小化子集加法或乘法以使两个给定的三元组相等

📅  最后修改于: 2021-04-21 23:29:16             🧑  作者: Mango

给定三个整数A,B,C表示一个三元组,三个整数P,Q,R表示另一个三元组。重复选择任何整数,并将其与该整数子集(A,B,C)中的所有元素相加或相乘,直到两个给定的三元组变为相等。任务是找到使两个三胞胎相等所需的此类操作的最小数量。

例子:

方法:请按照以下步骤解决给定的问题:

  • 在每个步骤中,一个整数乘以一个三元组的子集。整数可以选择为:
    • 另外:在每个步骤中,请尝试修复至少一个数字。因此,对于至少一个i,需要尝试加法的所有可能数的集合被限制为(B [i] – A [i])
    • 在乘法中:按照相同的逻辑,将m乘以一个子集,使得对于至少一个i,满足A [i] * m = B [i]
  • 到目前为止,所有运算都具有以下基本假设:在运算之后, A [i]的至少一个值将转换为B [i]。
  • 因此,使用递归来解决所有边缘情况并为我们提供转换要执行的最少操作数的问题。
  • 在上述步骤之后,打印最少的步骤数。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Utility function to check whether
// given two triplets are equal or not
bool equal(int a[], int b[])
{
    for (int i = 0; i < 3; i++) {
        if (a[i] != b[i]) {
            return false;
        }
    }
    return true;
}
 
// Utility function to find the number
// to be multiplied such that
// their differences become equal
int mulFac(int a, int b, int c, int d)
{
    if (b != a and (d - c) % (b - a) == 0) {
        return (d - c) / (b - a);
    }
    else {
        return 1;
    }
}
 
// Function to find minimum operations
void getMinOperations(int a[], int b[],
                      int& ans, int num = 0)
{
    // Base Case
    if (num >= ans)
        return;
 
    // If triplets are converted
    if (equal(a, b)) {
        ans = min(ans, num);
        return;
    }
 
    // Maximum possible ans is 3
    if (num >= 2)
        return;
 
    // Possible values that can be
    // added in next operation
    set add;
    add.insert(b[0] - a[0]);
    add.insert(b[1] - a[1]);
    add.insert(b[2] - a[2]);
 
    // Possible numbers that we can
    // multiply in next operation
    set mult;
    for (int i = 0; i < 3; i++) {
 
        // b[i] should be divisible by a[i]
        if (a[i] != 0
            && b[i] % a[i] == 0) {
            mult.insert(b[i] / a[i]);
        }
    }
 
    // Multiply integer to any 2 numbers
    // such that after multiplication
    // their difference becomes equal
    mult.insert(mulFac(a[0], a[1],
                       b[0], b[1]));
    mult.insert(mulFac(a[2], a[1],
                       b[2], b[1]));
    mult.insert(mulFac(a[0], a[2],
                       b[0], b[2]));
    mult.insert(0);
 
    // Possible subsets from triplet
    for (int mask = 1; mask <= 7; mask++) {
 
        // Subset to apply operation
        vector subset;
 
        for (int j = 0; j < 3; j++)
            if (mask & (1 << j))
                subset.push_back(j);
 
        // Apply addition on chosen subseet
        for (auto x : add) {
            int temp[3];
            for (int j = 0; j < 3; j++)
                temp[j] = a[j];
            for (auto e : subset)
                temp[e] += x;
 
            // Recursively find all
            // the operations
            getMinOperations(temp, b,
                             ans, num + 1);
        }
 
        // Applying multiplication
        // on chosen subseet
        for (auto x : mult) {
 
            int temp[3];
 
            for (int j = 0; j < 3; j++)
                temp[j] = a[j];
 
            for (auto e : subset)
                temp[e] *= x;
 
            // Recursively find all
            // the operations
            getMinOperations(temp, b,
                             ans, num + 1);
        }
    }
}
 
// Driver Code
int main()
{
    // Initial triplet
    int a[] = { 4, 5, 6 };
 
    // Final Triplet
    int b[] = { 0, 1, 0 };
 
    // Maximum possible answer = 3
    int ans = 3;
 
    // Function Call
    getMinOperations(a, b, ans);
 
    cout << ans << endl;
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
 
static int ans_max = 0;
 
// Utility function to check whether
// given two triplets are equal or not
static boolean equal(int[] a, int[] b)
{
    for(int i = 0; i < 3; i++)
    {
        if (a[i] != b[i])
        {
            return false;
        }
    }
    return true;
}
 
// Utility function to find the number
// to be multiplied such that
// their differences become equal
static int mulFac(int a, int b,
                  int c, int d)
{
    if (b != a && (d - c) % (b - a) == 0)
    {
        return (d - c) / (b - a);
    }
    else
    {
        return 1;
    }
}
 
// Function to find minimum operations
static void getMinOperations(int[] a, int[] b,
                             int ans, int num)
{
     
    // Base Case
    if (num >= ans)
    {
        return;
    }
     
    // If triplets are converted
    if (equal(a, b))
    {
        ans = Math.min(ans, num);
        ans_max = ans;
        return;
    }
     
    // Maximum possible ans is 3
    if (num >= 2)
    {
        return;
    }
     
    // Possible values that can be
    // added in next operation
    Set ad = new HashSet();
    ad.add(b[0] - a[0]);
    ad.add(b[1] - a[1]);
    ad.add(b[2] - a[2]);
     
    // Possible numbers that we can
    // multiply in next operation
    Set mult = new HashSet();
    for(int i = 0; i < 3; i++)
    {
         
        // b[i] should be divisible by a[i]
        if (a[i] != 0 && b[i] % a[i] == 0)
        {
            mult.add(b[i] / a[i]);
        }
    }
     
    // Multiply integer to any 2 numbers
    // such that after multiplication
    // their difference becomes equal
    mult.add(mulFac(a[0], a[1],
                    b[0], b[1]));
    mult.add(mulFac(a[2], a[1],
                    b[2], b[1]));
    mult.add(mulFac(a[0], a[2],
                    b[0], b[2]));
    mult.add(0);
     
    // Possible subsets from triplet
    for(int mask = 1; mask <= 7; mask++)
    {
         
        // Subset to apply operation
        Vector subset = new Vector();
        for(int j = 0; j < 3; j++)
        {
            if ((mask & (1 << j)) != 0)
            {
                subset.add(j);
            }
        }
         
        // Apply addition on chosen subseet
        for(int x : ad)
        {
            int[] temp = new int[3];
            for(int j = 0; j < 3; j++)
            {
                temp[j] = a[j];
            }
            for(int e:subset)
            {
                temp[e] += x;
            }
             
            // Recursively find all
            // the operations
            getMinOperations(temp, b, ans,
                             num + 1);
        }
         
        // Applying multiplication
        // on chosen subseet
        for(int x:mult)
        {
            int[] temp = new int[3];
            for(int j = 0; j < 3; j++)
            {
                temp[j] = a[j];
            }
            for(int e:subset)
            {
                temp[e] *= x;
            }
             
            // Recursively find all
            // the operations
            getMinOperations(temp, b,
                             ans, num + 1);
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Initial triplet
    int[] a = { 4, 5, 6 };
     
    // Final Triplet
    int[] b = { 0, 1, 0 };
     
    // Maximum possible answer = 3
    int ans = 3;
     
    // Function Call
    getMinOperations(a, b, ans, 0);
     
    System.out.println(ans_max);
}
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# Python3 program for the above approach
ans_max = 0
 
# Utility function to check whether
# given two triplets are equal or not
def equal(a, b):
     
    for i in range(3):
        if (a[i] != b[i]):
            return False
 
    return True
 
# Utility function to find the number
# to be multiplied such that
# their differences become equal
def mulFac(a, b, c, d):
     
    if (b != a and (d - c) % (b - a) == 0):
        return (d - c) // (b - a)
    else:
        return 1
 
# Function to find minimum operations
def getMinOperations(a, b, ans, num):
     
    global ans_max
     
    # Base Case
    if (num >= ans):
        return 0
 
    # If triplets are converted
    if (equal(a, b)):
        ans = min(ans, num)
        ans_max = ans
 
        return ans
 
    # Maximum possible ans is 3
    if (num >= 2):
        return 0
 
    # Possible values that can be
    # added in next operation
    add = {}
    add[(b[0] - a[0])] = 1
    add[(b[1] - a[1])] = 1
    add[(b[2] - a[2])] = 1
     
    # Possible numbers that we can
    # multiply in next operation
    mult = {}
     
    for i in range(3):
         
        # b[i] should be divisible by a[i]
        if (a[i] != 0 and b[i] % a[i] == 0):
            mult[b[i] // a[i]] = 1
 
    # Multiply integer to any 2 numbers
    # such that after multiplication
    # their difference becomes equal
    mult[mulFac(a[0], a[1], b[0], b[1])] = 1
    mult[mulFac(a[2], a[1], b[2], b[1])] = 1
    mult[mulFac(a[0], a[2], b[0], b[2])] = 1
    mult[0] = 1
 
    # Possible subsets from triplet
    for mask in range(1, 8):
         
        # Subset to apply operation
        subset = {}
 
        for j in range(3):
            if (mask & (1 << j)):
                subset[j] = 1
 
        # Apply addition on chosen subseet
        for x in add:
            temp = [0] * 3
            for j in range(3):
                temp[j] = a[j]
            for e in subset:
                temp[e] += x
 
            # Recursively find all
            # the operations
            getMinOperations(temp, b, ans,
                             num + 1)
 
        # Applying multiplication
        # on chosen subseet
        for x in mult:
            temp = [0] * 3
 
            for j in range(3):
                temp[j] = a[j]
 
            for e in subset:
                temp[e] *= x
 
            # Recursively find all
            # the operations
            getMinOperations(temp, b, ans,
                             num + 1)
 
    return ans
 
# Driver Code
if __name__ == '__main__':
     
    # Initial triplet
    a = [ 4, 5, 6 ]
  
    # Final Triplet
    b = [ 0, 1, 0 ]
 
    # Maximum possible answer = 3
    ans = 3
 
    # Function Call
    ans = getMinOperations(a, b, ans, 0)
 
    print(ans_max)
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
  static int ans_max = 0;
 
  // Utility function to check whether
  // given two triplets are equal or not
  static bool equal(int[] a, int[] b)
  {
    for(int i = 0; i < 3; i++)
    {
      if (a[i] != b[i])
      {
        return false;
      }
    }
    return true;
  }
 
  // Utility function to find the number
  // to be multiplied such that
  // their differences become equal
  static int mulFac(int a, int b,int c, int d)
  {
    if (b != a && (d - c) % (b - a) == 0)
    {
      return (d - c) / (b - a);
    }
    else
    {
      return 1;
    }
  }
 
  // Function to find minimum operations
  static void getMinOperations(int[] a, int[] b,int ans, int num)
  {
 
    // Base Case
    if (num >= ans)
    {
      return;
    }
 
    // If triplets are converted
    if (equal(a, b))
    {
      ans = Math.Min(ans, num);
      ans_max = ans;
      return;
    }
 
    // Maximum possible ans is 3
    if (num >= 2)
    {
      return;
    }
 
    // Possible values that can be
    // added in next operation
    HashSet ad = new HashSet();
    ad.Add(b[0] - a[0]);
    ad.Add(b[1] - a[1]);
    ad.Add(b[2] - a[2]);
 
    // Possible numbers that we can
    // multiply in next operation
    HashSet mult = new HashSet();
    for(int i = 0; i < 3; i++)
    {
 
      // b[i] should be divisible by a[i]
      if (a[i] != 0 && b[i] % a[i] == 0)
      {
        mult.Add(b[i] / a[i]);
 
      }
 
    }
 
    // Multiply integer to any 2 numbers
    // such that after multiplication
    // their difference becomes equal
    mult.Add(mulFac(a[0], a[1], b[0], b[1]));
    mult.Add(mulFac(a[2], a[1], b[2], b[1]));
    mult.Add(mulFac(a[0], a[2], b[0], b[2]));
    mult.Add(0);
 
    // Possible subsets from triplet
    for(int mask = 1; mask <= 7; mask++)
    {
 
      // Subset to apply operation
      List subset=new List();
      for(int j = 0; j < 3; j++)
      {
        if ((mask & (1 << j)) != 0)
        {
          subset.Add(j);
        }
      }
 
      // Apply addition on chosen subseet
      foreach(int x in ad)
      {
        int[] temp = new int[3];
        for(int j = 0; j < 3; j++)
        {
          temp[j] = a[j];
        }
        foreach(int e in subset)
        {
          temp[e] += x;
        }
 
        // Recursively find all
        // the operations
        getMinOperations(temp, b, ans,num + 1);
      }
 
      // Applying multiplication
      // on chosen subseet
      foreach(int x in mult)
      {
        int[] temp = new int[3];
        for(int j = 0; j < 3; j++)
        {
          temp[j] = a[j];
        }
        foreach(int e in subset)
        {
          temp[e] *= x;
        }
 
        // Recursively find all
        // the operations
        getMinOperations(temp, b,ans, num + 1);
      }
    }
 
  }
 
  // Driver Code
  static public void Main ()
  {
 
    // Initial triplet
    int[] a = { 4, 5, 6 };
 
    // Final Triplet
    int[] b = { 0, 1, 0 };
 
    // Maximum possible answer = 3
    int ans = 3;
 
    // Function Call
    getMinOperations(a, b, ans, 0);       
    Console.WriteLine(ans_max);
  }
}
 
// This code is contributed by rag2127


输出:
2

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