给定两个数字N和M ,任务是通过将N除N之外的所有偶数除数重复相加,找到将N转换为M所需的最小运算。如果无法进行转换,则打印-1 。
例子:
Input: N = 6, M = 24
Output: 4
Explanation:
Step1: Add 2 (2 is an even divisor and 2!= 6) to 6. Now N becomes 8.
Step2: Add 4 (4 is an even divisor and 4!= 8) to 8. Now N becomes 12.
Step3: Add 6 (6 is an even divisor and 6!=12) to 12. Now N becomes 18.
Step4: Add 6 (6 is an even divisor and 6!=18) to 18. Now N becomes 24 = M.
Hence, 4 steps are needed.
Input: N = 9, M = 17
Output: -1
Explanation:
There are no even divisors for 9 to add, so we cannot convert N to M.
天真的方法:最简单的解决方案是考虑一个数字的所有可能的偶数除数,然后递归地为它们计算答案,最后返回最小值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// INF is the maximum value
// which indicates Impossible state
const int INF = 1e7;
// Recursive Function that considers
// all possible even divisors of cur
int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
// Return 0 if cur == M
if (cur == M)
return 0;
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// means we can't transform cur to M
int op = INF;
// Loop to find even divisors of cur
for (int i = 2; i * i <= cur; i++) {
// if i is divisor of cur
if (cur % i == 0) {
// if i is even
if (i % 2 == 0) {
// Finding divisors
// recursively for cur+i
op = min(op,
1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i
&& (cur / i) % 2 == 0) {
// Find recursively
// for cur+(cur/i)
op = min(
op,
1 + min_op(
cur + (cur / i),
M));
}
}
}
// Return the answer
return op;
}
// Function that finds the minimum
// operation to reduce N to M
int min_operations(int N, int M)
{
int op = min_op(N, M);
// INF indicates impossible state
if (op >= INF)
cout << "-1";
else
cout << op << "\n";
}
// Driver Code
int main()
{
// Given N and M
int N = 6, M = 24;
// Function Call
min_operations(N, M);
return 0;
}
Java
// Java program for the above approach
class GFG{
// INF is the maximum value
// which indicates Impossible state
static int INF = (int) 1e7;
// Recursive Function that considers
// all possible even divisors of cur
static int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
// Return 0 if cur == M
if (cur == M)
return 0;
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// means we can't transform cur to M
int op = INF;
// Loop to find even divisors of cur
for (int i = 2; i * i <= cur; i++)
{
// if i is divisor of cur
if (cur % i == 0)
{
// if i is even
if (i % 2 == 0)
{
// Finding divisors
// recursively for cur+i
op = Math.min(op, 1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.min(op, 1 + min_op(
cur + (cur / i), M));
}
}
}
// Return the answer
return op;
}
// Function that finds the minimum
// operation to reduce N to M
static void min_operations(int N, int M)
{
int op = min_op(N, M);
// INF indicates impossible state
if (op >= INF)
System.out.print("-1");
else
System.out.print(op + "\n");
}
// Driver Code
public static void main(String[] args)
{
// Given N and M
int N = 6, M = 24;
// Function Call
min_operations(N, M);
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 program for the above approach
# INF is the maximum value
# which indicates Impossible state
INF = int(1e7);
# Recursive Function that considers
# all possible even divisors of cur
def min_op(cur, M):
# Indicates impossible state
if (cur > M):
return INF;
# Return 0 if cur == M
if (cur == M):
return 0;
# op stores the minimum operations
# required to transform cur to M
# Initially it is set to INF that
# means we can't transform cur to M
op = int(INF);
# Loop to find even divisors of cur
for i in range(2, int(cur ** 1 / 2) + 1):
# If i is divisor of cur
if (cur % i == 0):
# If i is even
if (i % 2 == 0):
# Finding divisors
# recursively for cur+i
op = min(op, 1 + min_op(cur + i, M));
# Check another divisor
if ((cur / i) != i and
(cur / i) % 2 == 0):
# Find recursively
# for cur+(cur/i)
op = min(op, 1 + min_op(
cur + (cur // i), M));
# Return the answer
return op;
# Function that finds the minimum
# operation to reduce N to M
def min_operations(N, M):
op = min_op(N, M);
# INF indicates impossible state
if (op >= INF):
print("-1");
else:
print(op);
# Driver Code
if __name__ == '__main__':
# Given N and M
N = 6;
M = 24;
# Function call
min_operations(N, M);
# This code is contributed by Amit Katiyar
C#
// C# program for the above approach
using System;
class GFG {
// INF is the maximum value
// which indicates Impossible state
static int INF = (int)1e7;
// Recursive Function that considers
// all possible even divisors of cur
static int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
// Return 0 if cur == M
if (cur == M)
return 0;
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// means we can't transform cur to M
int op = INF;
// Loop to find even divisors of cur
for (int i = 2; i * i <= cur; i++)
{
// if i is divisor of cur
if (cur % i == 0)
{
// if i is even
if (i % 2 == 0)
{
// Finding divisors
// recursively for cur+i
op = Math.Min(op,1 +
min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.Min(op, 1 +
min_op(cur +
(cur / i), M));
}
}
}
// Return the answer
return op;
}
// Function that finds the minimum
// operation to reduce N to M
static void min_operations(int N, int M)
{
int op = min_op(N, M);
// INF indicates impossible state
if (op >= INF)
Console.Write("-1");
else
Console.Write(op + "\n");
}
// Driver Code
public static void Main(String[] args)
{
// Given N and M
int N = 6, M = 24;
// Function Call
min_operations(N, M);
}
}
// This code is contributed by Amit Katiyar
C++
// C++ program for the above approach
#include
using namespace std;
// INF is the maximum value
// which indicates Impossible state
const int INF = 1e7;
const int max_size = 100007;
// Stores the dp states
int dp[max_size];
// Recursive Function that considers
// all possible even divisors of cur
int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for (int i = 2; i * i <= cur; i++) {
// if i is divisor of cur
if (cur % i == 0) {
// if i is even
if (i % 2 == 0) {
// Find recursively
// for cur+i
op = min(op, 1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0) {
// Find recursively
// for cur+(cur/i)
op = min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
}
// Function that counts the minimum
// operation to reduce N to M
int min_operations(int N, int M)
{
// Intialise dp state
for (int i = N; i <= M; i++) {
dp[i] = -1;
}
// Function Call
return min_op(N, M);
}
// Driver Code
int main()
{
// Given N and M
int N = 6, M = 24;
// Function Call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
cout << "-1";
else
cout << op << "\n";
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// INF is the maximum value
// which indicates Impossible state
static int INF = (int) 1e7;
static int max_size = 100007;
// Stores the dp states
static int []dp = new int[max_size];
// Recursive Function that considers
// all possible even divisors of cur
static int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for(int i = 2; i * i <= cur; i++)
{
// If i is divisor of cur
if (cur % i == 0)
{
// If i is even
if (i % 2 == 0)
{
// Find recursively
// for cur+i
op = Math.min(op,
1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i &&
(cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
}
// Function that counts the minimum
// operation to reduce N to M
static int min_operations(int N, int M)
{
// Intialise dp state
for(int i = N; i <= M; i++)
{
dp[i] = -1;
}
// Function call
return min_op(N, M);
}
// Driver Code
public static void main(String[] args)
{
// Given N and M
int N = 6, M = 24;
// Function call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
System.out.print("-1");
else
System.out.print(op + "\n");
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program for the
# above approach
# INF is the maximum value
# which indicates Impossible state
INF = 10000007;
max_size = 100007;
# Stores the dp states
dp = [0 for i in range(max_size)];
# Recursive Function
# that considers all
# possible even divisors
# of cur
def min_op(cur, M):
# Indicates impossible
# state
if (cur > M):
return INF;
if (cur == M):
return 0;
# Check dp[cur] is already
# calculated or not
if (dp[cur] != -1):
return dp[cur];
# op stores the minimum
# operations required to
# transform cur to M
# Initially it is set
# to INF that meanswe cur
# can't be transform to M
op = INF;
i = 2
# Loop to find even
# divisors of cur
while(i * i <= cur):
# if i is divisor of cur
if (cur % i == 0):
# if i is even
if(i % 2 == 0):
# Find recursively
# for cur+i
op = min(op, 1 + min_op(cur +
i, M));
# Check another divisor
if ((cur // i) != i and
(cur // i) % 2 == 0):
# Find recursively
# for cur+(cur/i)
op = min(op, 1 + min_op(cur +
(cur // i), M))
i += 1
# Finally store the current state
# result and return the answer
dp[cur] = op;
return op
# Function that counts the minimum
# operation to reduce N to M
def min_operations(N, M):
# Intialise dp state
for i in range(N, M + 1):
dp[i] = -1;
# Function Call
return min_op(N, M);
# Driver code
if __name__ == "__main__":
# Given N and M
N = 6
M = 24
# Function Call
op = min_operations(N, M);
# INF indicates impossible state
if (op >= INF):
print(-1)
else:
print(op)
# This code is contributed by rutvik_56
C#
// C# program for the above approach
using System;
class GFG{
// INF is the maximum value
// which indicates Impossible state
static int INF = (int) 1e7;
static int max_size = 100007;
// Stores the dp states
static int []dp = new int[max_size];
// Recursive Function that considers
// all possible even divisors of cur
static int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for(int i = 2; i * i <= cur; i++)
{
// If i is divisor of cur
if (cur % i == 0)
{
// If i is even
if (i % 2 == 0)
{
// Find recursively
// for cur+i
op = Math.Min(op, 1 +
min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i &&
(cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.Min(op, 1 +
min_op(cur +
(cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
}
// Function that counts the minimum
// operation to reduce N to M
static int min_operations(int N,
int M)
{
// Intialise dp state
for(int i = N; i <= M; i++)
{
dp[i] = -1;
}
// Function call
return min_op(N, M);
}
// Driver Code
public static void Main(String[] args)
{
// Given N and M
int N = 6, M = 24;
// Function call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
Console.Write("-1");
else
Console.Write(op + "\n");
}
}
// This code is contributed by Rajput-Ji
4
时间复杂度: O(2 N )
辅助空间: O(1)
高效的方法:想法是使用动态编程并以天真的方法存储重叠的子问题状态,以有效地计算答案。请按照以下步骤解决问题:
- 为所有N <= i <= M初始化dp表dp [i] = -1 。
- 考虑一个数字的所有偶数除数,并从所有整数中找出最小值。
- 最后,将结果存储在dp []中并返回答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// INF is the maximum value
// which indicates Impossible state
const int INF = 1e7;
const int max_size = 100007;
// Stores the dp states
int dp[max_size];
// Recursive Function that considers
// all possible even divisors of cur
int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for (int i = 2; i * i <= cur; i++) {
// if i is divisor of cur
if (cur % i == 0) {
// if i is even
if (i % 2 == 0) {
// Find recursively
// for cur+i
op = min(op, 1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0) {
// Find recursively
// for cur+(cur/i)
op = min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
}
// Function that counts the minimum
// operation to reduce N to M
int min_operations(int N, int M)
{
// Intialise dp state
for (int i = N; i <= M; i++) {
dp[i] = -1;
}
// Function Call
return min_op(N, M);
}
// Driver Code
int main()
{
// Given N and M
int N = 6, M = 24;
// Function Call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
cout << "-1";
else
cout << op << "\n";
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// INF is the maximum value
// which indicates Impossible state
static int INF = (int) 1e7;
static int max_size = 100007;
// Stores the dp states
static int []dp = new int[max_size];
// Recursive Function that considers
// all possible even divisors of cur
static int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for(int i = 2; i * i <= cur; i++)
{
// If i is divisor of cur
if (cur % i == 0)
{
// If i is even
if (i % 2 == 0)
{
// Find recursively
// for cur+i
op = Math.min(op,
1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i &&
(cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
}
// Function that counts the minimum
// operation to reduce N to M
static int min_operations(int N, int M)
{
// Intialise dp state
for(int i = N; i <= M; i++)
{
dp[i] = -1;
}
// Function call
return min_op(N, M);
}
// Driver Code
public static void main(String[] args)
{
// Given N and M
int N = 6, M = 24;
// Function call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
System.out.print("-1");
else
System.out.print(op + "\n");
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program for the
# above approach
# INF is the maximum value
# which indicates Impossible state
INF = 10000007;
max_size = 100007;
# Stores the dp states
dp = [0 for i in range(max_size)];
# Recursive Function
# that considers all
# possible even divisors
# of cur
def min_op(cur, M):
# Indicates impossible
# state
if (cur > M):
return INF;
if (cur == M):
return 0;
# Check dp[cur] is already
# calculated or not
if (dp[cur] != -1):
return dp[cur];
# op stores the minimum
# operations required to
# transform cur to M
# Initially it is set
# to INF that meanswe cur
# can't be transform to M
op = INF;
i = 2
# Loop to find even
# divisors of cur
while(i * i <= cur):
# if i is divisor of cur
if (cur % i == 0):
# if i is even
if(i % 2 == 0):
# Find recursively
# for cur+i
op = min(op, 1 + min_op(cur +
i, M));
# Check another divisor
if ((cur // i) != i and
(cur // i) % 2 == 0):
# Find recursively
# for cur+(cur/i)
op = min(op, 1 + min_op(cur +
(cur // i), M))
i += 1
# Finally store the current state
# result and return the answer
dp[cur] = op;
return op
# Function that counts the minimum
# operation to reduce N to M
def min_operations(N, M):
# Intialise dp state
for i in range(N, M + 1):
dp[i] = -1;
# Function Call
return min_op(N, M);
# Driver code
if __name__ == "__main__":
# Given N and M
N = 6
M = 24
# Function Call
op = min_operations(N, M);
# INF indicates impossible state
if (op >= INF):
print(-1)
else:
print(op)
# This code is contributed by rutvik_56
C#
// C# program for the above approach
using System;
class GFG{
// INF is the maximum value
// which indicates Impossible state
static int INF = (int) 1e7;
static int max_size = 100007;
// Stores the dp states
static int []dp = new int[max_size];
// Recursive Function that considers
// all possible even divisors of cur
static int min_op(int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for(int i = 2; i * i <= cur; i++)
{
// If i is divisor of cur
if (cur % i == 0)
{
// If i is even
if (i % 2 == 0)
{
// Find recursively
// for cur+i
op = Math.Min(op, 1 +
min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i &&
(cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.Min(op, 1 +
min_op(cur +
(cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
}
// Function that counts the minimum
// operation to reduce N to M
static int min_operations(int N,
int M)
{
// Intialise dp state
for(int i = N; i <= M; i++)
{
dp[i] = -1;
}
// Function call
return min_op(N, M);
}
// Driver Code
public static void Main(String[] args)
{
// Given N and M
int N = 6, M = 24;
// Function call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
Console.Write("-1");
else
Console.Write(op + "\n");
}
}
// This code is contributed by Rajput-Ji
4
时间复杂度: O(N * sqrt(N))
辅助空间: O(M)