给定两个数字N和M,任务是找到将N更改为M或-1(如果不可能)的最小移动次数。在一步中,将任何不等于 1 的除数和数字本身添加到当前数字上。
例子:
Input: N = 4, M = 24
Output: 5
Explanation: the number 24 can be reached starting from 4 using 5 operations: 4->6->8->12->18->24.
Input: N = 4, M = 576
Output: 14
接近:建立一个图,其中顶点从N到M号和有从边缘顶点V1至V2顶点V2是否可以从V1使用从问题陈述正好一个操作来获得。为了解决这个问题,在这个图中找到从顶点N到顶点M的最短路径。这可以使用广度优先搜索算法来完成。请按照以下步骤解决问题:
- 初始化一个布尔数组visited[]来存储一个特定的数字是否被计算在内。
- 用值false填充 bool 数组visited[] 的所有索引,并将visited[N]的值设置为true。
- 初始化成对队列q以存储访问的数量和完成的操作数量。
- 将{N, 0}对推入对q的队列中。
- 在一个范围内迭代,直到对q的队列不为空。
- 将变量aux初始化为队列q的前对的第一个值,将cont初始化为队列q的前对的第二个值。
- 从对q的队列中弹出前对。
- 如果aux等于M,则返回cont的值。
- 在范围[2, aux 1/2 ] 中迭代并执行以下步骤。
- 如果i是aux的因子,则执行以下步骤。
- 如果aux+i小于等于M且visited[i+aux]为false,则将visited[aux+i]的值设置为true并将{aux+i, cont+1}对推入对q。
- 如果aux+aux/i小于等于M并且visited[aux/i+aux]为false,则将visited[aux+aux/i]的值设置为true并推送对{aux+aux/i, cont+1}进入对q的队列。
- 如果i是aux的因子,则执行以下步骤。
- 返回-1 ,因为不可能使N等于M。
下面是上述方法的实现。
C++
// C++ program for the above approach.
#include
using namespace std;
// Function to find the minimum number
// of moves to make N and M equal.
int countOperations(int N, int M)
{
// Array to maintain the numbers
// included.
bool visited[100001];
fill(visited, visited + 100001, false);
// pair of vertex, count
queue > Q;
Q.push(make_pair(N, 0));
visited[N] = true;
// run bfs from N
while (!Q.empty()) {
int aux = Q.front().first;
int cont = Q.front().second;
Q.pop();
// if we reached goal
if (aux == M)
return cont;
// Iterate in the range
for (int i = 2; i * i <= aux; i++)
// If i is a factor of aux
if (aux % i == 0) {
// If i is less than M-aux and
// is not included earlier.
if (aux + i <= M && !visited[aux + i]) {
Q.push(make_pair(aux + i, cont + 1));
visited[aux + i] = true;
}
// If aux/i is less than M-aux and
// is not included earlier.
if (aux + aux / i <= M
&& !visited[aux + aux / i]) {
Q.push(
make_pair(aux + aux / i, cont + 1));
visited[aux + aux / i] = true;
}
}
}
// Not possible
return -1;
}
// Driver Code
int main()
{
int N = 4, M = 24;
cout << countOperations(N, M);
return 0;
}
Java
// Java program for above approach
import java.util.*;
class GFG{
static class pair
{
T first;
V second;
}
static pair make_pair(int f, int s)
{
pair p = new pair<>();
p.first = f; p.second = s;
return p;
}
// Function to find the minimum number
// of moves to make N and M equal.
static int countOperations(int N, int M)
{
// Array to maintain the numbers
// included.
boolean[] visited = new boolean[100001];
Arrays.fill(visited, false);
// Pair of vertex, count
Queue> Q = new LinkedList<>();
Q.add(make_pair(N, 0));
visited[N] = true;
// Run bfs from N
while (!Q.isEmpty())
{
int aux = Q.peek().first;
int cont = Q.peek().second;
Q.remove();
// If we reached goal
if (aux == M)
return cont;
// Iterate in the range
for(int i = 2; i * i <= aux; i++)
// If i is a factor of aux
if (aux % i == 0)
{
// If i is less than M-aux and
// is not included earlier.
if (aux + i <= M && !visited[aux + i])
{
Q.add(make_pair(aux + i, cont + 1));
visited[aux + i] = true;
}
// If aux/i is less than M-aux and
// is not included earlier.
if (aux + aux / i <= M &&
!visited[aux + aux / i])
{
Q.add(make_pair(aux + aux / i,
cont + 1));
visited[aux + aux / i] = true;
}
}
}
// Not possible
return -1;
}
// Driver Code
public static void main(String[] args)
{
int N = 4, M = 24;
System.out.println(countOperations(N, M));
}
}
// This code is contributed by hritikrommie
Python3
# Python3 program for the above approach.
# Function to find the minimum number
# of moves to make N and M equal.
def countOperations(N, M):
# Array to maintain the numbers
# included.
visited = [False] * (100001)
# Pair of vertex, count
Q = []
Q.append([N, 0])
visited[N] = True
# Run bfs from N
while (len(Q) > 0):
aux = Q[0][0]
cont = Q[0][1]
Q.pop(0)
# If we reached goal
if (aux == M):
return cont
# Iterate in the range
i = 2
while i * i <= aux:
# If i is a factor of aux
if (aux % i == 0):
# If i is less than M-aux and
# is not included earlier.
if (aux + i <= M and not visited[aux + i]):
Q.append([aux + i, cont + 1])
visited[aux + i] = True
# If aux/i is less than M-aux and
# is not included earlier.
if (aux + int(aux / i) <= M and not
visited[aux + int(aux / i)]):
Q.append([aux + int(aux / i), cont + 1])
visited[aux + int(aux / i)] = True
i += 1
# Not possible
return -1
# Driver code
N, M = 4, 24
print(countOperations(N, M))
# This code is contributed by mukesh07
C#
// C# program for the above approach.
using System;
using System.Collections;
class GFG
{
// Function to find the minimum number
// of moves to make N and M equal.
static int countOperations(int N, int M)
{
// Array to maintain the numbers
// included.
bool[] visited = new bool[100001];
// pair of vertex, count
Queue Q = new Queue();
Q.Enqueue(new Tuple(N, 0));
visited[N] = true;
// run bfs from N
while (Q.Count > 0) {
int aux = ((Tuple)(Q.Peek())).Item1;
int cont = ((Tuple)(Q.Peek())).Item2;
Q.Dequeue();
// if we reached goal
if (aux == M)
return cont;
// Iterate in the range
for (int i = 2; i * i <= aux; i++)
// If i is a factor of aux
if (aux % i == 0)
{
// If i is less than M-aux and
// is not included earlier.
if (aux + i <= M && !visited[aux + i]) {
Q.Enqueue(new Tuple(aux + i, cont + 1));
visited[aux + i] = true;
}
// If aux/i is less than M-aux and
// is not included earlier.
if (aux + aux / i <= M
&& !visited[aux + aux / i]) {
Q.Enqueue(new Tuple(aux + aux / i, cont + 1));
visited[aux + aux / i] = true;
}
}
}
// Not possible
return -1;
}
static void Main ()
{
int N = 4, M = 24;
Console.WriteLine(countOperations(N, M));
}
}
// This code is contributed by suresh07.
Javascript
输出
5
时间复杂度: O(N*sqrt(N))
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。