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++ 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 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) |
# 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# 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 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 |
Yes No No No Yes Yes No Yes No
Time Complexity: O(N + Q)
Auxiliary Space: O(N)
Related Articles: