给定三个整数A,B,C表示一个三元组,三个整数P,Q,R表示另一个三元组。重复选择任何整数,并将其与该整数子集(A,B,C)中的所有元素相加或相乘,直到两个给定的三元组变为相等。任务是找到使两个三胞胎相等所需的此类操作的最小数量。
例子:
Input: (A, B, C) = (3, 4, 5), (P, Q, R) = (6, 3, 10)
Output: 2
Explanation:
Step 1: Multiply 2 with all elements of the subset {3, 5}. Triplet (A, B, C) becomes (6, 4, 10).
Step 2: Add -1 to the subset {4}. Triplet (A, B, C) becomes (6, 3, 10) which is same as the triplet (P, Q, R).
Therefore, the minimum number of operations required is 2.
Input: (A, B, C) = (7, 6, 8), (p, q, r) = (2, 2, 2)
Output: 2
Explanation:
Step 1: Multiply all elements of the subset (7, 6, 8) with 0. (A, B, C) modifies to (0, 0, 0).
Step 2: Add 2 to all elements of the subset (0, 0, 0). (A, B, C) modifies to (2, 2, 2) same as the triplet (P, Q, R).
Therefore, the minimum number of operations required is 2.
方法:请按照以下步骤解决给定的问题:
- 在每个步骤中,将一个整数加或乘以一个三元组的子集。整数可以选择为:
- 另外:在每个步骤中,请尝试修复至少一个数字。因此,对于至少一个i,需要尝试加法的所有可能数的集合被限制为(B [i] – A [i]) 。
- 在乘法中:按照相同的逻辑,将m乘以一个子集,使得对于至少一个i,满足A [i] * m = B [i] 。
- 到目前为止,所有运算都具有以下基本假设:在运算之后, A [i]的至少一个值将转换为B [i]。
Consider the following Case: A[] = [2, 3, 4] and B[] = [-20, – 1, 18]
The above transformation can be done in just two steps by multiplying all numbers by 19 and then adding -58 to each number.
Such cases have to be taken care of separately.
- 因此,使用递归来解决所有边缘情况并为我们提供转换要执行的最少操作数的问题。
- 在上述步骤之后,打印最少的步骤数。
下面是上述方法的实现:
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)