给定两个整数N和M ,任务是找出将N转换为M所需的最小运算次数。每个操作都涉及添加N的当前值的主要因子之一。如果可以得到 M,则打印操作次数。否则,打印-1 。
例子:
Input: N = 6, M = 10
Output: 2
Explanation:
Prime factors of 6 are [2, 3].
Adding 2 to N, we obtain 8.
The prime factor of 8 is [2].
Adding 2 to N, we obtain 10, which is the desired result.
Hence, total steps = 2
Input: N = 2, M = 3
Output: -1
Explanation:
There is no way to convert N = 2 to M = 3.
方法:
该问题可以通过使用 BFS 获得达到 M 的最小步长和埃拉托色尼筛来预计算素数来解决。
请按照以下步骤解决问题:
- 使用 Sieve 存储和预计算所有素数。
- 现在,如果 N 已经等于 M,则打印 0,因为不需要加法运算。
- 将此问题可视化为执行BFS的图形问题。在每个级别上,通过添加素因子,从前一级别的 N 值中存储可到达的数字。
- 现在,首先在队列中插入(N, 0) ,其中 N 表示值,0 表示达到该值的操作数。
- 在队列的每一层,通过提取 front() 处的元素,逐一遍历所有元素,并执行以下操作:
- 将q.front().first() 存储在newNum 中,将q.front().second() 存储在distance 中,其中newNum是当前值, distance是达到此值所需的操作数。
- 将newNum 的所有质因数存储在一个集合中。
- 如果newNum等于M ,则打印距离,因为它是所需的最少操作。
- 如果newNum大于 M,则中断。
- 否则,newNum 小于 M。因此,通过将其质因数 i 一个一个相加来更新 newNum 并将(newNum + i, distance + 1) 存储在队列中,并为下一级别重复上述步骤。
- 如果搜索继续到队列变空的级别,则表示无法从N 中获取M。打印-1。
下面是上述方法的实现:
C++
// C++ program to find the minimum
// steps required to convert a number
// N to M.
#include
using namespace std;
// Array to store shortest prime
// factor of every integer
int spf[100009];
// Function to precompute
// shortest prime factors
void sieve()
{
memset(spf, -1, 100005);
for (int i = 2; i * i <= 100005; i++) {
for (int j = i; j <= 100005; j += i) {
if (spf[j] == -1) {
spf[j] = i;
}
}
}
}
// Function to insert distinct prime factors
// of every integer into a set
set findPrimeFactors(set s,
int n)
{
// Store distinct prime
// factors
while (n > 1) {
s.insert(spf[n]);
n /= spf[n];
}
return s;
}
// Function to return minimum
// steps using BFS
int MinimumSteps(int n, int m)
{
// Queue of pairs to store
// the current number and
// distance from root.
queue > q;
// Set to store distinct
// prime factors
set s;
// Run BFS
q.push({ n, 0 });
while (!q.empty()) {
int newNum = q.front().first;
int distance = q.front().second;
q.pop();
// Find out the prime factors of newNum
set k = findPrimeFactors(s,
newNum);
// Iterate over every prime
// factor of newNum.
for (auto i : k) {
// If M is obtained
if (newNum == m) {
// Return number of
// operations
return distance;
}
// If M is exceeded
else if (newNum > m) {
break;
}
// Otherwise
else {
// Update and store the new
// number obtained by prime factor
q.push({ newNum + i,
distance + 1 });
}
}
}
// If M cannot be obtained
return -1;
}
// Driver code
int main()
{
int N = 7, M = 16;
sieve();
cout << MinimumSteps(N, M);
}
Java
// Java program to find the minimum
// steps required to convert a number
// N to M.
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Array to store shortest prime
// factor of every integer
static int []spf = new int[100009];
// Function to precompute
// shortest prime factors
static void sieve()
{
for(int i = 0; i < 100005; i++)
spf[i] = -1;
for(int i = 2; i * i <= 100005; i++)
{
for(int j = i; j <= 100005; j += i)
{
if (spf[j] == -1)
{
spf[j] = i;
}
}
}
}
// Function to insert distinct prime factors
// of every integer into a set
static HashSet findPrimeFactors(HashSet s,
int n)
{
// Store distinct prime
// factors
while (n > 1)
{
s.add(spf[n]);
n /= spf[n];
}
return s;
}
// Function to return minimum
// steps using BFS
static int MinimumSteps(int n, int m)
{
// Queue of pairs to store
// the current number and
// distance from root.
Queue q = new LinkedList<>();
// Set to store distinct
// prime factors
HashSet s = new HashSet();
// Run BFS
q.add(new pair(n, 0));
while (!q.isEmpty())
{
int newNum = q.peek().first;
int distance = q.peek().second;
q.remove();
// Find out the prime factors of newNum
HashSet k = findPrimeFactors(s,
newNum);
// Iterate over every prime
// factor of newNum.
for(int i : k)
{
// If M is obtained
if (newNum == m)
{
// Return number of
// operations
return distance;
}
// If M is exceeded
else if (newNum > m)
{
break;
}
// Otherwise
else
{
// Update and store the new
// number obtained by prime factor
q.add(new pair(newNum + i,
distance + 1 ));
}
}
}
// If M cannot be obtained
return -1;
}
// Driver code
public static void main(String[] args)
{
int N = 7, M = 16;
sieve();
System.out.print(MinimumSteps(N, M));
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program to find the minimum
# steps required to convert a number
# N to M.
# Array to store shortest prime
# factor of every integer
spf = [-1 for i in range(100009)];
# Function to precompute
# shortest prime factors
def sieve():
i=2
while(i * i <= 100006):
for j in range(i, 100006, i):
if (spf[j] == -1):
spf[j] = i;
i += 1
# Function to append distinct prime factors
# of every integer into a set
def findPrimeFactors(s, n):
# Store distinct prime
# factors
while (n > 1):
s.add(spf[n]);
n //= spf[n];
return s;
# Function to return minimum
# steps using BFS
def MinimumSteps( n, m):
# Queue of pairs to store
# the current number and
# distance from root.
q = []
# Set to store distinct
# prime factors
s = set()
# Run BFS
q.append([ n, 0 ])
while (len(q) != 0):
newNum = q[0][0]
distance = q[0][1]
q.pop(0);
# Find out the prime factors of newNum
k = findPrimeFactors(s, newNum);
# Iterate over every prime
# factor of newNum.
for i in k:
# If M is obtained
if (newNum == m):
# Return number of
# operations
return distance;
# If M is exceeded
elif (newNum > m):
break;
# Otherwise
else:
# Update and store the new
# number obtained by prime factor
q.append([ newNum + i, distance + 1 ]);
# If M cannot be obtained
return -1;
# Driver code
if __name__=='__main__':
N = 7
M = 16;
sieve();
print( MinimumSteps(N, M))
# This code is contributed by rutvik_56
C#
// C# program to find the minimum
// steps required to convert a number
// N to M.
using System;
using System.Collections.Generic;
class GFG{
class pair
{
public int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Array to store shortest prime
// factor of every integer
static int []spf = new int[100009];
// Function to precompute
// shortest prime factors
static void sieve()
{
for(int i = 0; i < 100005; i++)
spf[i] = -1;
for(int i = 2; i * i <= 100005; i++)
{
for(int j = i; j <= 100005; j += i)
{
if (spf[j] == -1)
{
spf[j] = i;
}
}
}
}
// Function to insert distinct prime factors
// of every integer into a set
static HashSet findPrimeFactors(HashSet s,
int n)
{
// Store distinct prime
// factors
while (n > 1)
{
s.Add(spf[n]);
n /= spf[n];
}
return s;
}
// Function to return minimum
// steps using BFS
static int MinimumSteps(int n, int m)
{
// Queue of pairs to store
// the current number and
// distance from root.
Queue q = new Queue();
// Set to store distinct
// prime factors
HashSet s = new HashSet();
// Run BFS
q.Enqueue(new pair(n, 0));
while (q.Count != 0)
{
int newNum = q.Peek().first;
int distance = q.Peek().second;
q.Dequeue();
// Find out the prime factors of newNum
HashSet k = findPrimeFactors(s,
newNum);
// Iterate over every prime
// factor of newNum.
foreach(int i in k)
{
// If M is obtained
if (newNum == m)
{
// Return number of
// operations
return distance;
}
// If M is exceeded
else if (newNum > m)
{
break;
}
// Otherwise
else
{
// Update and store the new
// number obtained by prime factor
q.Enqueue(new pair(newNum + i,
distance + 1));
}
}
}
// If M cannot be obtained
return -1;
}
// Driver code
public static void Main(String[] args)
{
int N = 7, M = 16;
sieve();
Console.Write(MinimumSteps(N, M));
}
}
// This code is contributed by Princi Singh
输出:
2
时间复杂度: O(N* log(N))
辅助空间: O(N)