Open In App

Check if the player can reach the target co-ordinates after performing given moves from origin

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N describing N moves. A player standing at origin (0, 0). In the first move, the player can move either right or left by distance arr[1]. In the second move, the player can move up or down by distance arr[2], In the third move player can move left or right by distance arr[3], and so on till arr[N]. That is on odd moves player moves along the X coordinate and on even moves, the player moves along the Y coordinate. The task for this problem is to check whether coordinate (X, Y) is reachable from (0, 0) if the player performs these moves optimally. If this is possible print “Yes” else print “No”

Examples : 

Input: A[] = {2, 1, 3}, X = -1, Y = 1
Output: Yes
Explanation:

Example 1

Following is one of the possible ways to  reach at (-1, 1)

  • In first move player moves to (2, 0) by moving along positive direction of X co-ordinate by distance 2
  • In second move player moves to (2, 1) by moving along positive direction of Y co-ordinate by distance 1
  • In Third move player moves to (-1, 1) by moving along negative direction of X co-ordinate by distance 3

Input: A[] = {1, 2, 3, 4}, X = 5, Y = 5
Output: No

Naive approach: The basic way to solve the problem is as follows:

Visiting all possible co-ordinates by recursive brute force in exponential time. 

Complexity Analysis:
Time Complexity: O(2N)
Auxiliary Space: O(1)

Efficient Approach:  The above approach can be optimized based on the following idea

Important observation is that this problem can independently solved for both coordinates X and Y.

Lets reduce this problem to 1 dimension. Players starts from 0.

  • Problem 1: Player has to reach on coordinate X by following moves {A[1], A[3], A[5], …….} on each move player can move back and forth by distance A[i].
  • Problem 2: Player has to reach on coordinate Y by following moves {A[2], A[4], A[6], ……..} on each move player can move back and forth by distance A[i].

Dynamic programming can be used to solve this problem for each independent coordinate.

  • dp[i][j] is either True or False, represents whether coordinate j is reachable or not in first i moves. 
  • recurrence relation : dp[i][j] = max(dp[i + 1][j + A[i]], dp[i + 1][j – A[i]])

it can be observed that there are N * AMax states but the recursive function is called exponential times. That means that some states are called repeatedly. So the idea is to store the value of states. This can be done using recursive structure intact and just store the value in a HashMap and whenever the function is called, return the value store without computing 

  • if both X and Y coordinates are reachable independently then coordinate (X, Y) is also reachable for player.

Follow the steps below to solve the problem:

  • Creating two different array A1[] and A2[] for two independent problems and calling recursive function recur() for both.
  • Create a recursive function that takes two parameters i representing i’th move and j represents current coordinate.
  • Call recursive function for both moving right or up and left or down.
  • Check the base case  if at the end of Nth move we are on T which is target co-ordinate then return 1 else return 0.
  • Create an 2d array of dp[501][10001] with initially filled with -1.
  • If the answer for a particular state is computed then save it in dp[i][j].
  • If the answer for a particular state is already computed then just return dp[i][j].
  • Create two variables isPossibleX and isPossibleY for storing answer of two independent problems.
  • If isPossibleX and isPossibleY both are 1 then print “Yes” else print “No”.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// dp table initialized with - 1
int dp[501][20001];
 
// recursive function to tell whether
// given coordinate (X, Y) is reachable
// or not from origin
int recur(int i, int j, int T, vector<int>& A)
{
 
    // base case
    if (i == A.size()) {
        // if T is possible return 1
        if (j == T)
            return 1;
        else
            return 0;
    }
 
    // if answer for current state is already
    // calculated then just return dp[i][j]
    // + 10000 is offset value to also include
    // negative numbers in states
    if (dp[i][j + 10000] != -1)
        return dp[i][j + 10000];
 
    int ans = 0;
 
    // calling recursive function to move Right
    // in case of X coordinate or UP in case of
    // Y coordinate by distance A[i]
    ans = max(ans, recur(i + 1, j + A[i], T, A));
 
    // calling recursive function to move Left
    // in case of X coordinate or Down in case of
    // Y coordinate by distance A[i]
    ans = max(ans, recur(i + 1, j - A[i], T, A));
 
    // save and return dp value
    return dp[i][j + 10000] = ans;
}
 
// Function to check whether given
// Coordinates (X, Y) is reachable
// from origin
void isReachable(int A[], int N, int X, int Y)
{
    // creating two different arrays A1
    // for solving X coordinate and A2
    // for solving Y coordinate
    vector<int> A1, A2;
 
    // filling both the A1 and A2
    for (int i = 0; i < N; i++) {
        if (i % 2 == 0)
            A1.push_back(A[i]);
        else
            A2.push_back(A[i]);
    }
 
    // filling dp table with -1
    memset(dp, -1, sizeof(dp));
 
    // to check whether Reaching X
    // coordinate is possible by moves
    // {A[1], A[3], A[5], A[7], .....}
    int isPossibleX = recur(0, 0, X, A1);
 
    // filling dp table with -1
    memset(dp, -1, sizeof(dp));
 
    // to check whether Reaching Y
    // coordinate is possible by moves
    // {A[2], A[4], A[6], ........}
    int isPossibleY = recur(0, 0, Y, A2);
 
    // if reaching X and Y coordinates Both
    // are possible then only reaching on (X, Y)
    // is possible by player
    if (isPossibleX and isPossibleY)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}
 
// Driver Code
int main()
{
    // Input 1
    int A[] = { 2, 1, 3 };
    int N = sizeof(A) / sizeof(A[0]);
    int X = -1, Y = 1;
 
    // Function Call
    isReachable(A, N, X, Y);
 
    // Input 2
    int A1[] = { 1, 2, 3, 4 };
    int N1 = sizeof(A1) / sizeof(A1[0]);
    int X1 = 5, Y1 = 5;
 
    // Function Call
    isReachable(A1, N1, X1, Y1);
    return 0;
}


Java




// Java code to implement the approach
import java.io.*;
import java.util.*;
 
class GFG {
 
  // dp table initialized with - 1
  static int[][] dp = new int[501][20001];
 
  // recursive function to tell whether
  // given coordinate (X, Y) is reachable
  // or not from origin
  public static int recur(int i, int j, int T,
                          Vector<Integer> A)
  {
 
    // base case
    if (i == A.size()) {
      // if T is possible return 1
      if (j == T)
        return 1;
      else
        return 0;
    }
 
    // if answer for current state is already
    // calculated then just return dp[i][j]
    // + 10000 is offset value to also include
    // negative numbers in states
    if (dp[i][j + 10000] != -1)
      return dp[i][j + 10000];
 
    int ans = 0;
 
    // calling recursive function to move Right
    // in case of X coordinate or UP in case of
    // Y coordinate by distance A[i]
    ans = Math.max(ans,
                   recur(i + 1, j + A.get(i), T, A));
 
    // calling recursive function to move Left
    // in case of X coordinate or Down in case of
    // Y coordinate by distance A[i]
    ans = Math.max(ans,
                   recur(i + 1, j - A.get(i), T, A));
 
    // save and return dp value
    return dp[i][j + 10000] = ans;
  }
 
  // Function to check whether given
  // Coordinates (X, Y) is reachable
  // from origin
  public static void isReachable(int[] A, int N, int X,
                                 int Y)
  {
    // creating two different arrays A1
    // for solving X coordinate and A2
    // for solving Y coordinate
    Vector<Integer> A1 = new Vector<>();
    Vector<Integer> A2 = new Vector<>();
 
    // filling both the A1 and A2
    for (int i = 0; i < N; i++) {
      if (i % 2 == 0)
        A1.add(A[i]);
      else
        A2.add(A[i]);
    }
    // filling dp table with -1
    for (int[] row : dp)
      Arrays.fill(row, -1);
 
    // to check whether Reaching X
    // coordinate is possible by moves
    // {A[1], A[3], A[5], A[7], .....}
    int isPossibleX = recur(0, 0, X, A1);
 
    // filling dp table with -1
    for (int[] row : dp)
      Arrays.fill(row, -1);
 
    // to check whether Reaching Y
    // coordinate is possible by moves
    // {A[2], A[4], A[6], ........}
    int isPossibleY = recur(0, 0, Y, A2);
 
    // if reaching X and Y coordinates Both
    // are possible then only reaching on (X, Y)
    // is possible by player
    if (isPossibleX == 1 && isPossibleY == 1)
      System.out.println("Yes");
    else
      System.out.println("No");
  }
 
  public static void main(String[] args)
  {
    // Input 1
    int[] A = { 2, 1, 3 };
    int N = A.length;
    int X = -1, Y = 1;
 
    // Function Call
    isReachable(A, N, X, Y);
 
    // Input 2
    int[] A1 = { 1, 2, 3, 4 };
    int N1 = A1.length;
    int X1 = 5, Y1 = 5;
 
    // Function Call
    isReachable(A1, N1, X1, Y1);
  }
}
 
// This code is contributed by lokesh.


Python3




# Python3 code to implement the approach
 
# dp table initialized with -1
dp = [[-1 for j in range(20001)] for i in range(501)]
 
# recursive function to tell whether
# given coordinate (X, Y) is reachable
# or not from origin
def recur(i, j, T, A):
    # base case
    if i == len(A):
        # if T is possible return 1
        if j == T:
            return 1
        else:
            return 0
 
    # if answer for current state is already
    # calculated then just return dp[i][j]
    # + 10000 is offset value to also include
    # negative numbers in states
    if dp[i][j + 10000] != -1:
        return dp[i][j + 10000]
 
    ans = 0
 
    # calling recursive function to move Right
    # in case of X coordinate or UP in case of
    # Y coordinate by distance A[i]
    ans = max(ans, recur(i + 1, j + A[i], T, A))
 
    # calling recursive function to move Left
    # in case of X coordinate or Down in case of
    # Y coordinate by distance A[i]
    ans = max(ans, recur(i + 1, j - A[i], T, A))
 
    # save and return dp value
    dp[i][j + 10000] = ans
    return dp[i][j + 10000]
 
# Function to check whether given
# Coordinates (X, Y) is reachable
# from origin
def isReachable(A, N, X, Y):
    # creating two different arrays A1
    # for solving X coordinate and A2
    # for solving Y coordinate
    A1 = []
    A2 = []
 
    # filling both the A1 and A2
    for i in range(N):
        if i % 2 == 0:
            A1.append(A[i])
        else:
            A2.append(A[i])
 
    # to check whether Reaching X
    # coordinate is possible by moves
    # {A[1], A[3], A[5], A[7], .....}
    isPossibleX = recur(0, 0, X, A1)
 
    # to check whether Reaching Y
    # coordinate is possible by moves
    # {A[2], A[4], A[6], ........}
    isPossibleY = recur(0, 0, Y, A2)
 
    # if reaching X and Y coordinates Both
    # are possible then only reaching on (X, Y)
    # is possible by player
    if isPossibleX and isPossibleY:
        print("Yes")
    else:
        print("No")
 
# Driver Code
 
# Input 1
A = [2, 1, 3]
N = len(A)
X = -1
Y = 1
 
# Function Call
isReachable(A, N, X, Y)
dp = [[-1 for j in range(20001)] for i in range(501)]
 
# Input 2
A1 = [1, 2, 3, 4]
N1 = len(A1)
X1 = 5
Y1 = 5
 
# Function Call
isReachable(A1, N1, X1, Y1)
 
# This code is contributed by Potta Lokesh


Javascript




// Javascript code to implement the approach
 
// dp table initialized with - 1
//let dp[501][20001];
let dp=new Array(501);
for(let i=0; i<501; i++)
    dp[i]=new Array(20001);
 
// recursive function to tell whether
// given coordinate (X, Y) is reachable
// or not from origin
function recur(i, j, T, A)
{
 
    // base case
    if (i == A.length) {
        // if T is possible return 1
        if (j == T)
            return 1;
        else
            return 0;
    }
 
    // if answer for current state is already
    // calculated then just return dp[i][j]
    // + 10000 is offset value to also include
    // negative numbers in states
    if (dp[i][j + 10000] != -1)
        return dp[i][j + 10000];
 
    let ans = 0;
 
    // calling recursive function to move Right
    // in case of X coordinate or UP in case of
    // Y coordinate by distance A[i]
    ans = Math.max(ans, recur(i + 1, j + A[i], T, A));
 
    // calling recursive function to move Left
    // in case of X coordinate or Down in case of
    // Y coordinate by distance A[i]
    ans = Math.max(ans, recur(i + 1, j - A[i], T, A));
 
    // save and return dp value
    return dp[i][j + 10000] = ans;
}
 
// Function to check whether given
// Coordinates (X, Y) is reachable
// from origin
function isReachable(A, N, X, Y)
{
    // creating two different arrays A1
    // for solving X coordinate and A2
    // for solving Y coordinate
    let A1=[], A2=[];
 
    // filling both the A1 and A2
    for (let i = 0; i < N; i++) {
        if (i % 2 == 0)
            A1.push(A[i]);
        else
            A2.push(A[i]);
    }
 
    // filling dp table with -1
    for(let i=0; i<501; i++)
        for(let j=0; j<20001; j++)
            dp[i][j]=-1;
             
    // to check whether Reaching X
    // coordinate is possible by moves
    // {A[1], A[3], A[5], A[7], .....}
    let isPossibleX = recur(0, 0, X, A1);
 
    // filling dp table with -1
    for(let i=0; i<501; i++)
        for(let j=0; j<20001; j++)
            dp[i][j]=-1;
     
    // to check whether Reaching Y
    // coordinate is possible by moves
    // {A[2], A[4], A[6], ........}
    let isPossibleY = recur(0, 0, Y, A2);
 
    // if reaching X and Y coordinates Both
    // are possible then only reaching on (X, Y)
    // is possible by player
    if (isPossibleX && isPossibleY)
        document.write("Yes");
    else
        document.write("No");
}
 
// Driver Code
    // Input 1
    let A = [ 2, 1, 3 ];
    let N = A.length;
    let X = -1, Y = 1;
 
    // Function Call
    isReachable(A, N, X, Y);
     
    document.write("<br>");
     
    // Input 2
    let A1 = [ 1, 2, 3, 4 ];
    let N1 = A1.length;
    let X1 = 5, Y1 = 5;
 
    // Function Call
    isReachable(A1, N1, X1, Y1);


C#




using System;
using System.Collections.Generic;
 
class GFG {
    // dp table initialized with - 1
    static int[, ] dp = new int[501, 20001];
 
    // recursive function to tell whether
    // given coordinate (X, Y) is reachable
    // or not from origin
    static int recur(int i, int j, int T, List<int> A)
    {
        // base case
        if (i == A.Count) {
            // if T is possible return 1
            if (j == T)
                return 1;
            else
                return 0;
        }
 
        // if answer for current state is already
        // calculated then just return dp[i][j]
        // + 10000 is offset value to also include
        // negative numbers in states
        if (dp[i, j + 10000] != -1)
            return dp[i, j + 10000];
 
        int ans = 0;
 
        // calling recursive function to move Right
        // in case of X coordinate or UP in case of
        // Y coordinate by distance A[i]
        ans = Math.Max(ans, recur(i + 1, j + A[i], T, A));
 
        // calling recursive function to move Left
        // in case of X coordinate or Down in case of
        // Y coordinate by distance A[i]
        ans = Math.Max(ans, recur(i + 1, j - A[i], T, A));
 
        // save and return dp value
        return dp[i, j + 10000] = ans;
    }
 
       static void isReachable(int[] A, int N, int X, int Y)
    {
        // creating two different lists A1
        // for solving X coordinate and A2
        // for solving Y coordinate
        List<int> A1 = new List<int>();
        List<int> A2 = new List<int>();
 
        // filling both the A1 and A2
        for (int i = 0; i < N; i++)
        {
            if (i % 2 == 0)
                A1.Add(A[i]);
            else
                A2.Add(A[i]);
        }
         
        for (int i = 0; i < 501; i++)
            for (int j = 0; j < 20001; j++)
                dp[i, j] = -1;
 
        // to check whether Reaching X
        // coordinate is possible by moves
        // {A[1], A[3], A[5], A[7], .....}
        int isPossibleX = recur(0, 0, X, A1);
 
        for (int i = 0; i < 501; i++)
            for (int j = 0; j < 20001; j++)
                dp[i, j] = -1;
 
        // to check whether Reaching Y
        // coordinate is possible by moves
        // {A[2], A[4], A[6], ........}
        int isPossibleY = recur(0, 0, Y, A2);
 
        // if reaching X and Y coordinates Both
        // are possible then only reaching on (X, Y)
        // is possible by player
        if (isPossibleX == 1 && isPossibleY == 1)
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
 
    static void Main(string[] args)
    {
        // Input 1
        int[] A = { 2, 1, 3 };
        int N = A.Length;
        int X = -1, Y = 1;
 
        // Function Call
        isReachable(A, N, X, Y);
 
        // Input 2
        int[] A1 = { 1, 2, 3, 4 };
        int N1 = A1.Length;
        int X1 = 5, Y1 = 5;
 
        // Function Call
        isReachable(A1, N1, X1, Y1);
    }
}


Output

Yes
No

Complexity Analysis:
Time Complexity: O(N * AMax
Auxiliary Space: O(N * AMax)

Where AMax is Maximum value in array A[]

Related Articles :



Last Updated : 23 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads