📌  相关文章
📜  通过跳两个给定长度来检查是否有可能达到一个数字

📅  最后修改于: 2021-04-22 03:33:18             🧑  作者: Mango

给定一个起始位置“ k”和两个跳跃大小“ d1”和“ d2”,我们的任务是找到可能的达到“ x”的最小跳跃次数。

在任何位置P处,我们都可以跳到以下位置:

  • P + d1P – d1
  • P + d2P – d2

例子:

Input : k = 10, d1 = 4, d2 = 6 and x = 8 
Output : 2
1st step 10 + d1 = 14
2nd step 14 - d2 = 8

Input : k = 10, d1 = 4, d2 = 6 and x = 9
Output : -1
-1 indicates it is not possible to reach x.

在上一篇文章中,我们讨论了通过对两个给定长度进行跳转来检查K是否可到达数字列表的策略。

在这里,不是数字列表,而是给我们一个整数x ,如果可以从k到达整数,则任务是找到所需的最小步数或跳跃数。

我们将使用广度优先搜索解决此问题:
方法

  • 检查k是否可以到达“ x”。如果x满足(x – k)%gcd(d1,d2)= 0,则可以从k获得数字x
  • 如果x可达:
    1. 维护哈希表以存储已访问的位置。
    2. 从位置k开始应用bfs算法。
    3. 如果您以“ stp”步长到达位置P,则可以以“ stp + 1”步长到达p + d1位置。
    4. 如果位置P是要求的位置“ x”,则达到P的步骤就是答案

下图描述了算法如何找出达到x = 8(k = 10,d1 = 4和d2 = 6)所需的步数。
算法实例

下面是上述方法的实现:

C++
#include 
using namespace std;
  
// Function to perform BFS traversal to
// find minimum number of step needed
// to reach x from K
int minStepsNeeded(int k, int d1, int d2, int x)
{
    // Calculate GCD of d1 and d2
    int gcd = __gcd(d1, d2);
  
    // If position is not reachable
    // return -1
    if ((k - x) % gcd != 0)
        return -1;
  
    // Queue for BFS
    queue > q;
  
    // Hash Table for marking
    // visited positions
    unordered_set visited;
  
    // we need 0 steps to reach K
    q.push({ k, 0 });
  
    // Mark starting position
    // as visited
    visited.insert(k);
  
    while (!q.empty()) {
  
        int s = q.front().first;
  
        // stp is the number of steps
        // to reach position s
        int stp = q.front().second;
  
        if (s == x)
            return stp;
  
        q.pop();
  
        if (visited.find(s + d1) == visited.end()) {
  
            // if position not visited
            // add to queue and mark visited
            q.push({ s + d1, stp + 1 });
  
            visited.insert(s + d1);
        }
  
        if (visited.find(s + d2) == visited.end()) {
            q.push({ s + d2, stp + 1 });
            visited.insert(s + d2);
        }
  
        if (visited.find(s - d1) == visited.end()) {
            q.push({ s - d1, stp + 1 });
            visited.insert(s - d1);
        }
        if (visited.find(s - d2) == visited.end()) {
            q.push({ s - d2, stp + 1 });
            visited.insert(s - d2);
        }
    }
}
  
// Driver Code
int main()
{
    int k = 10, d1 = 4, d2 = 6, x = 8;
  
    cout << minStepsNeeded(k, d1, d2, x);
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG
{
static class pair
{ 
    int first, second; 
    public pair(int first, int second) 
    { 
        this.first = first; 
        this.second = second; 
    } 
} 
static int __gcd(int a, int b) 
{ 
    if (b == 0) 
        return a; 
    return __gcd(b, a % b); 
      
}
// Function to perform BFS traversal to
// find minimum number of step needed
// to reach x from K
static int minStepsNeeded(int k, int d1, 
                          int d2, int x)
{
    // Calculate GCD of d1 and d2
    int gcd = __gcd(d1, d2);
  
    // If position is not reachable
    // return -1
    if ((k - x) % gcd != 0)
        return -1;
  
    // Queue for BFS
    Queue q = new LinkedList<>();
  
    // Hash Table for marking
    // visited positions
    HashSet visited = new HashSet<>();
  
    // we need 0 steps to reach K
    q.add(new pair(k, 0 ));
  
    // Mark starting position
    // as visited
    visited.add(k);
  
    while (!q.isEmpty()) 
    {
        int s = q.peek().first;
  
        // stp is the number of steps
        // to reach position s
        int stp = q.peek().second;
  
        if (s == x)
            return stp;
  
        q.remove();
  
        if (!visited.contains(s + d1)) 
        {
  
            // if position not visited
            // add to queue and mark visited
            q.add(new pair(s + d1, stp + 1));
  
            visited.add(s + d1);
        }
  
        if (visited.contains(s + d2)) 
        {
            q.add(new pair(s + d2, stp + 1));
            visited.add(s + d2);
        }
  
        if (!visited.contains(s - d1))
        {
            q.add(new pair(s - d1, stp + 1));
            visited.add(s - d1);
        }
        if (!visited.contains(s - d2)) 
        {
            q.add(new pair(s - d2, stp + 1));
            visited.add(s - d2);
        }
    }
    return Integer.MIN_VALUE;
}
  
// Driver Code
public static void main(String[] args)
{
    int k = 10, d1 = 4, d2 = 6, x = 8;
  
    System.out.println(minStepsNeeded(k, d1, d2, x));
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the approach
from math import gcd as __gcd
from collections import deque as queue
  
# Function to perform BFS traversal to
# find minimum number of step needed
# to reach x from K
def minStepsNeeded(k, d1, d2, x):
      
    # Calculate GCD of d1 and d2
    gcd = __gcd(d1, d2)
  
    # If position is not reachable
    # return -1
    if ((k - x) % gcd != 0):
        return -1
  
    # Queue for BFS
    q = queue()
  
    # Hash Table for marking
    # visited positions
    visited = dict()
  
    # we need 0 steps to reach K
    q.appendleft([k, 0])
  
    # Mark starting position
    # as visited
    visited[k] = 1
  
    while (len(q) > 0):
  
        sr = q.pop()
        s, stp = sr[0], sr[1]
  
        # stp is the number of steps
        # to reach position s
        if (s == x):
            return stp
  
        if (s + d1 not in visited):
  
            # if position not visited
            # add to queue and mark visited
            q.appendleft([(s + d1), stp + 1])
  
            visited[(s + d1)] = 1
  
        if (s + d2 not in visited):
            q.appendleft([(s + d2), stp + 1])
            visited[(s + d2)] = 1
  
        if (s - d1 not in visited):
            q.appendleft([(s - d1), stp + 1])
            visited[(s - d1)] = 1
  
        if (s - d2 not in visited):
            q.appendleft([(s - d2), stp + 1])
            visited[(s - d2)] = 1
  
# Driver Code
k = 10
d1 = 4
d2 = 6
x = 8
  
print(minStepsNeeded(k, d1, d2, x))
  
# This code is contributed by Mohit Kumar


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;             
      
class GFG
{
public class pair
{ 
    public int first, second; 
    public pair(int first, int second) 
    { 
        this.first = first; 
        this.second = second; 
    } 
} 
  
static int __gcd(int a, int b) 
{ 
    if (b == 0) 
        return a; 
    return __gcd(b, a % b); 
      
}
  
// Function to perform BFS traversal to
// find minimum number of step needed
// to reach x from K
static int minStepsNeeded(int k, int d1, 
                          int d2, int x)
{
    // Calculate GCD of d1 and d2
    int gcd = __gcd(d1, d2);
  
    // If position is not reachable
    // return -1
    if ((k - x) % gcd != 0)
        return -1;
  
    // Queue for BFS
    Queue q = new Queue();
  
    // Hash Table for marking
    // visited positions
    HashSet visited = new HashSet();
  
    // we need 0 steps to reach K
    q.Enqueue(new pair(k, 0));
  
    // Mark starting position
    // as visited
    visited.Add(k);
  
    while (q.Count != 0) 
    {
        int s = q.Peek().first;
  
        // stp is the number of steps
        // to reach position s
        int stp = q.Peek().second;
  
        if (s == x)
            return stp;
  
        q.Dequeue();
  
        if (!visited.Contains(s + d1)) 
        {
  
            // if position not visited
            // add to queue and mark visited
            q.Enqueue(new pair(s + d1, stp + 1));
  
            visited.Add(s + d1);
        }
  
        if (!visited.Contains(s + d2)) 
        {
            q.Enqueue(new pair(s + d2, stp + 1));
            visited.Add(s + d2);
        }
  
        if (!visited.Contains(s - d1))
        {
            q.Enqueue(new pair(s - d1, stp + 1));
            visited.Add(s - d1);
        }
        if (!visited.Contains(s - d2)) 
        {
            q.Enqueue(new pair(s - d2, stp + 1));
            visited.Add(s - d2);
        }
    }
    return int.MinValue;
}
  
// Driver Code
public static void Main(String[] args)
{
    int k = 10, d1 = 4, d2 = 6, x = 8;
  
    Console.WriteLine(minStepsNeeded(k, d1, d2, x));
}
}
  
// This code is contributed by PrinciRaj1992


输出:
2