Frog Jump in C++


Suppose there is a frog that is crossing a river. The river is divided into x units and at each unit there may be a stone. The frog can jump on a stone, but not water. Here we have a list of stones' positions in sorted ascending order sequence, we have to check whether the frog is able to cross the river by landing on the last stone, or not. Initially, the frog is on the first stone and assume the first jump must be of 1 unit.

When the frog's current jump was k units, then its next jump must be either k - 1, k, or k + 1 units. And frog can only jump in the forward direction.

So if the given array is like [0,1,3,4,5,7,9,10,12], then the answer will be true as, the frog can jump to the 1 unit to 2nd stone, 2 units to 3rd stone, then again 2 units to 4th stone, then 3 units to 6th stone, 4 units to 7th stone and finally 5 units to 8th stone.

To solve this, we will follow these steps −

  • Define a map called visited
  • Define a function canCross(), this will take an array stones, pos initialize it with 0, k initialize it with 0,
  • key := pos OR (left shift k 11 bits)
  • if key is present in the visited, then −
    • return visited[key]
  • for initialize i := pos + 1, when i < size of stones, update (increase i by 1), do −
    • gap := stones[i] - stones[pos]
    • if gap < k - 1, then −
      • Ignore following part, skip to the next iteration
    • if gap > k + 1, then −
      • visited[key] := false
      • return false
    • if call the function canCross(stones, i, gap) is non-zero, then −
      • visited[key] = true
      • return true
  • visited[key] = true when (pos is same as size of stones - 1) otherwise false
  • return visited[key]

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
class Solution {
public:
   unordered_map < lli, int > visited;
   bool canCross(vector<int>& stones, int pos = 0, int k = 0) {
      lli key = pos | k << 11;
      if(visited.find(key) != visited.end())return visited[key];
      for(int i = pos + 1; i < stones.size(); i++){
         int gap = stones[i] - stones[pos];
         if(gap < k - 1)continue;
         if(gap > k + 1){
            return visited[key] = false;
         }
         if(canCross(stones, i, gap))return visited[key] = true;
      }
      return visited[key] = (pos == stones.size() - 1);
   }
};
main(){
   Solution ob;
   vector<int> v = {0,1,3,5,6,8,12,17};
   cout << (ob.canCross(v));
}

Input

0,1,3,5,6,8,12,17

Output

1

Updated on: 01-Jun-2020

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements