Open In App

Queries to check if traversal is possible from (1,1) to (2, N)

Last Updated : 28 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a grid of size, 2 rows * N columns and array Q[][2] of size M, the task for this problem is to check traversal from (1, 1) to (2, N) is possible or not in the given grid for each query given X and Y, block cell (X, Y) if it is open or open cell (X, Y) if it is blocked. Initially, all cells are open for traversal.

Note: Open cells allow traversal through that cell and blocked cell does not allow traversal through that cell.

Examples:

Input: N = 5, Q[][2] = {{2, 3}, {1, 4}, {2, 4}, {2, 3}, {1, 4}}
Output: Yes
No
No
No
Yes
Explanation: Initially all cells are open for traversal

  • query 1 : (2, 3) was open for traversal and now after performing first query it is blocked. Traversal from (1, 1) to (2, N) is still possible. 
  • query 2 : (1, 4) was open for traversal and now after performing second query it is blocked. Traversal from (1, 1) to (2, N) is not possible. 
  • query 3 : (2, 4) was open for traversal and now after performing third query it is blocked. Traversal from (1, 1) to (2, N) is not possible.
  • query 4 : (2, 3) was blocked for traversal and now after performing fourth query it is open. Traversal from (1, 1) to (2, N) is not possible.
  • query 5 : (1, 4) was blocked for traversal and now after performing fifth query it is open. Traversal from (1, 1) to (2, N) is possible.

Input: int N = 2, Q[][2] = {{2, 1}, {1, 2}, {1, 2}, {1, 2}};
Output: Yes
No
Yes
No

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

The basic way to solve this problem is to update grid for each query and with DFS (Depth First Search) check if traversal from (1, 1) to (2, N) is possible or not for each query.

Time Complexity: O(N * Q)
Auxiliary Space: O(N)

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

  • Greedy algorithms can be used to solve this problem.
  • Count of Blocks can be tracked and if blocks are zero then answer will be “Yes” else “No”.

Follow the steps below to solve the problem:

  • 2d array grid[2][N] is created initially with all values zero.
  • variable CNT is created for tracking the number of blocks initially with a value of zero.
  • Iterating for each M query and for each query updating grid[2][N].
  • if CNT is zero then print “Yes” or else “No” for each query.  

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if path from (1, 1)
// to (2, N) exist or not for each
// query
void countWays(int N, int Q[][2], int M)
{
 
    // Simulating grid
    vector<vector<int> > grid(2, vector<int>(N, 0));
 
    // Counter that indicates number of
    // blockades
    int cnt = 0;
 
    // Iterating for all queries
    for (int i = 0; i < M; i++) {
 
        // X and Y for current query
        int X = Q[i][0] - 1, Y = Q[i][1] - 1;
 
        // If the current grid location
        // is blocked
        if (grid[X][Y]) {
 
            // Open the current
            // grid location
            grid[X][Y] = 0;
 
            // Only one blockade
            if (Y == 0) {
 
                // Removing single blockade
                cnt = cnt - grid[X - 1][Y + 1];
            }
 
            // Only one blockade
            else if (Y == N - 1) {
 
                // Removing single blockade
                cnt = cnt - grid[X + 1][Y - 1];
            }
 
            // Three blockades
            else {
 
                // Removing three blockades
                cnt = cnt - grid[X ^ 1][Y - 1];
                cnt = cnt - grid[X ^ 1][Y];
                cnt = cnt - grid[X ^ 1][Y + 1];
            }
        }
 
        // If the current grid location
        // is open
        else {
 
            // Close the current
            // grid location
            grid[X][Y] = 1;
 
            // Only one blockade
            if (Y == 0) {
 
                // Removing single blockade
                cnt = cnt + grid[X - 1][Y + 1];
            }
 
            // Only one blockade
            else if (Y == N - 1) {
 
                // Removing single blockade
                cnt = cnt + grid[X + 1][Y - 1];
            }
 
            // Three blockades
            else {
 
                // Removing three blockades
                cnt = cnt + grid[X ^ 1][Y - 1];
                cnt = cnt + grid[X ^ 1][Y];
                cnt = cnt + grid[X ^ 1][Y + 1];
            }
        }
 
        // If there are no blockade
        // print yes
        if (cnt == 0)
            cout << "Yes" << endl;
 
        // If there are blockade
        // print no
        else
            cout << "No" << endl;
    }
}
 
// Driver Code
int main()
{
 
    // Input 1
    int N = 5, Q[][2] = {
        { 2, 3 }, { 1, 4 }, { 2, 4 }, { 2, 3 }, { 1, 4 }
    };
    int M = 5;
 
    // Function Call
    countWays(N, Q, M);
 
    cout << endl;
 
    // Input 2
    int N1 = 2,
        Q1[][2]
        = { { 2, 1 }, { 1, 2 }, { 1, 2 }, { 1, 2 } };
    int M1 = 4;
 
    // Function Call
    countWays(N1, Q1, M1);
    return 0;
}


Java




// Java code to implement the approach
import java.util.*;
 
class GFG {
 
  static int N, M;
 
  // Counter that indicates number of
  // blockades
  static int cnt;
 
  // Simulating grid
  static int[][] grid, Q;
 
  // Function to check if path from (1, 1)
  // to (2, N) exist or not for each
  // query
  static void countWays(int N, int[][] Q, int M)
  {
 
    // Iterating for all queries
    for (int i = 0; i < M; i++) {
 
      // X and Y for current query
      int X = Q[i][0] - 1, Y = Q[i][1] - 1;
 
      // If the current grid location
      // is blocked
      if (grid[X][Y] == 1) {
 
        // Open the current
        // grid location
        grid[X][Y] = 0;
 
        // Only one blockade
        if (Y == 0) {
 
          // Removing single blockade
          cnt -= grid[X - 1][Y + 1];
        }
 
        // Only one blockade
        else if (Y == N - 1) {
 
          // Removing single blockade
          cnt -= grid[X + 1][Y - 1];
        }
 
        // Three blockades
        else {
 
          // Removing three blockades
          cnt -= grid[X ^ 1][Y - 1];
          cnt -= grid[X ^ 1][Y];
          cnt -= grid[X ^ 1][Y + 1];
        }
      }
 
      // If the current grid location
      // is open
      else {
 
        // Close the current
        // grid location
        grid[X][Y] = 1;
 
        // Only one blockade
        if (Y == 0) {
 
          // Removing single blockade
          cnt += grid[X - 1][Y + 1];
        }
 
        // Only one blockade
        else if (Y == N - 1) {
 
          // Removing single blockade
          cnt += grid[X + 1][Y - 1];
        }
 
        // Three blockades
        else {
 
          // Removing three blockades
          cnt += grid[X ^ 1][Y - 1];
          cnt += grid[X ^ 1][Y];
          cnt += grid[X ^ 1][Y + 1];
        }
      }
 
      // If there are no blockade
      // print yes
      if (cnt == 0) {
        System.out.println("Yes");
      }
 
      // If there are blockade
      // print no
      else {
        System.out.println("No");
      }
    }
  }
 
  // Driver Code
  public static void main(String[] args)
  {
 
    // Input 1
    N = 5;
    Q = new int[][] {
      { 2, 3 }, { 1, 4 }, { 2, 4 }, { 2, 3 }, { 1, 4 }
    };
    M = 5;
 
    grid = new int[2][N];
 
    // Function Call
    countWays(N, Q, M);
 
    System.out.println();
 
    // Input 2
    N = 2;
    Q = new int[][] {
      { 2, 1 }, { 1, 2 }, { 1, 2 }, { 1, 2 }
    };
    M = 4;
 
    grid = new int[2][N];
 
    // Function Call
    countWays(N, Q, M);
  }
}
 
// This Code is Contributed by Prasad Kandekar(prasad264)


Python3




# Python code to implement the approach
 
# Function to check if path from (1, 1) to (2, N) exist or not for each query
def countWays(N, Q, M):
    # Simulating grid
    grid = [[0 for j in range(N)] for i in range(2)]
 
    # Counter that indicates number of blockades
    cnt = 0
 
    # Iterating for all queries
    for i in range(M):
        # X and Y for current query
        X, Y = Q[i][0] - 1, Q[i][1] - 1
 
        # If the current grid location is blocked
        if grid[X][Y]:
            # Open the current grid location
            grid[X][Y] = 0
 
            # Only one blockade
            if Y == 0:
                # Removing single blockade
                cnt -= grid[X - 1][Y + 1]
            # Only one blockade
            elif Y == N - 1:
                # Removing single blockade
                cnt -= grid[X + 1][Y - 1]
            # Three blockades
            else:
                # Removing three blockades
                cnt -= grid[X ^ 1][Y - 1]
                cnt -= grid[X ^ 1][Y]
                cnt -= grid[X ^ 1][Y + 1]
        # If the current grid location is open
        else:
            # Close the current grid location
            grid[X][Y] = 1
 
            # Only one blockade
            if Y == 0:
                # Removing single blockade
                cnt += grid[X - 1][Y + 1]
            # Only one blockade
            elif Y == N - 1:
                # Removing single blockade
                cnt += grid[X + 1][Y - 1]
            # Three blockades
            else:
                # Removing three blockades
                cnt += grid[X ^ 1][Y - 1]
                cnt += grid[X ^ 1][Y]
                cnt += grid[X ^ 1][Y + 1]
 
        # If there are no blockade print Yes
        if cnt == 0:
            print("Yes")
        # If there are blockades print No
        else:
            print("No")
 
# Driver Code
if __name__ == "__main__":
    # Input 1
    N = 5
    Q = [[2, 3], [1, 4], [2, 4], [2, 3], [1, 4]]
    M = 5
 
    # Function Call
    countWays(N, Q, M)
    print()
 
    # Input 2
    N1 = 2
    Q1 = [[2, 1], [1, 2], [1, 2], [1, 2]]
    M1 = 4
 
    # Function Call
    countWays(N1, Q1, M1)


C#




// C# code to implement the approach
 
using System;
 
public class GFG {
 
    static int N, M;
 
    // Counter that indicates number of blockades
    static int cnt;
 
    // Simulating grid
    static int[, ] grid, Q;
 
    // Function to check if path from (1, 1) to (2, N) exist
    // or not for each query
    static void countWays(int N, int[, ] Q, int M)
    {
 
        // Iterating for all queries
        for (int i = 0; i < M; i++) {
 
            // X and Y for current query
            int X = Q[i, 0] - 1, Y = Q[i, 1] - 1;
 
            // If the current grid location is blocked
            if (grid[X, Y] == 1) {
 
                // Open the current grid location
                grid[X, Y] = 0;
 
                // Only one blockade
                if (Y == 0) {
 
                    // Removing single blockade
                    cnt -= grid[X - 1, Y + 1];
                }
 
                // Only one blockade
                else if (Y == N - 1) {
 
                    // Removing single blockade
                    cnt -= grid[X + 1, Y - 1];
                }
 
                // Three blockades
                else {
 
                    // Removing three blockades
                    cnt -= grid[X ^ 1, Y - 1];
                    cnt -= grid[X ^ 1, Y];
                    cnt -= grid[X ^ 1, Y + 1];
                }
            }
 
            // If the current grid location is open
            else {
 
                // Close the current grid location
                grid[X, Y] = 1;
 
                // Only one blockade
                if (Y == 0) {
 
                    // Removing single blockade
                    cnt += grid[X - 1, Y + 1];
                }
 
                // Only one blockade
                else if (Y == N - 1) {
 
                    // Removing single blockade
                    cnt += grid[X + 1, Y - 1];
                }
 
                // Three blockades
                else {
 
                    // Removing three blockades
                    cnt += grid[X ^ 1, Y - 1];
                    cnt += grid[X ^ 1, Y];
                    cnt += grid[X ^ 1, Y + 1];
                }
            }
 
            // If there are no blockade print yes
            if (cnt == 0) {
                Console.WriteLine("Yes");
            }
 
            // If there are blockade print no
            else {
                Console.WriteLine("No");
            }
        }
    }
 
    static public void Main()
    {
 
        // Code
        // Input 1
        N = 5;
        Q = new int[, ] {
            { 2, 3 }, { 1, 4 }, { 2, 4 }, { 2, 3 }, { 1, 4 }
        };
        M = 5;
 
        grid = new int[2, N];
 
        // Function Call
        countWays(N, Q, M);
 
        Console.WriteLine();
 
        // Input 2
        N = 2;
        Q = new int[, ] {
            { 2, 1 }, { 1, 2 }, { 1, 2 }, { 1, 2 }
        };
        M = 4;
 
        grid = new int[2, N];
 
        // Function Call
        countWays(N, Q, M);
    }
}
 
// This code is contributed by karthik


Javascript




// JavaScript code to implement the approach
 
// Function to check if path from (1, 1) to (2, N) exist or not for each query
function countWays(N, Q, M) {
// Simulating grid
var grid = new Array(2);
for (var i = 0; i < 2; i++) {
grid[i] = new Array(N).fill(0);
}
 
// Counter that indicates number of blockades
var cnt = 0;
 
// Iterating for all queries
for (var i = 0; i < M; i++) {
// X and Y for current query
var X = Q[i][0] - 1;
var Y = Q[i][1] - 1;
// If the current grid location is blocked
if (grid[X][Y]) {
  // Open the current grid location
  grid[X][Y] = 0;
 
  // Only one blockade
  if (Y == 0) {
    // Removing single blockade
    cnt -= grid[X - 1][Y + 1];
  }
  // Only one blockade
  else if (Y == N - 1) {
    // Removing single blockade
    cnt -= grid[X + 1][Y - 1];
  }
  // Three blockades
  else {
    // Removing three blockades
    cnt -= grid[X ^ 1][Y - 1];
    cnt -= grid[X ^ 1][Y];
    cnt -= grid[X ^ 1][Y + 1];
  }
}
// If the current grid location is open
else {
  // Close the current grid location
  grid[X][Y] = 1;
 
  // Only one blockade
  if (Y == 0) {
    // Removing single blockade
    cnt += grid[X - 1][Y + 1];
  }
  // Only one blockade
  else if (Y == N - 1) {
    // Removing single blockade
    cnt += grid[X + 1][Y - 1];
  }
  // Three blockades
  else {
    // Removing three blockades
    cnt += grid[X ^ 1][Y - 1];
    cnt += grid[X ^ 1][Y];
    cnt += grid[X ^ 1][Y + 1];
  }
}
// If there are no blockade print Yes
if (cnt == 0) {
  console.log("Yes");
}
// If there are blockades print No
else {
  console.log("No");
}
}
}
 
// Driver Code
if (true) {
// Input 1
var N = 5;
var Q = [[2, 3], [1, 4], [2, 4], [2, 3], [1, 4]];
var M = 5;
 
// Function Call
countWays(N, Q, M);
console.log();
 
// Input 2
var N1 = 2;
var Q1 = [[2, 1], [1, 2], [1, 2], [1, 2]];
var M1 = 4;
 
// Function Call
countWays(N1, Q1, M1);
}
 
//This code is contributed by shivamsharma215


Output

Yes
No
No
No
Yes

Yes
No
Yes
No

Time Complexity: O(N + Q)  
Auxiliary Space: O(N)

Related Articles:



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads