CSES Solutions - Grid Paths (DP)
Last Updated :
27 Mar, 2024
Consider an N X N grid whose squares may have traps. It is not allowed to move to a square with a trap. Your task is to calculate the number of paths from the upper-left square to the lower-right square. You can only move right or down.
Note: '.
' denotes an empty cell, and '*'
 denotes a trap.
Grid PathsExamples:
Input: N = 4, grid[][] = {"....", ".*..", "...*", "*..."}
Output: 3
Explanation: There are 3 ways to reach the lower-right square, starting from the upper-left square.
Input: N = 3, grid[][] = {"...", "...", "..*"}
Output: 0
Explanation: There is no way to reach the lower-right square, starting from the upper-left square.
Approach: To solve the problem, follow the below idea:
The problem can be solved using Dynamic Programming. Maintain a dp[][] table such that dp[r][c] = number of ways to reach row r, column c from cell(0, 0).
We say there is one way to reach (0,0), dp[0][0] = 1.
When navigating the grid where each cell contains either a '.'
 or a '#'
, we can move either right or down. The number of ways to reach a particular cell is the sum of the ways to reach the cell above it and the ways to reach the cell to its left. Additionally, any cell containing a '#'
 is inaccessible (with zero ways to reach it). So, for each each cell (i, j), dp[i][j] = dp[i - 1][j] + dp[i][j - 1].
Step-by-step algorithm:
- Maintain a dp[][] array such that dp[i][j] stores the number of ways to reach cell(i, j) from cell(0, 0).
- Initialize all the cells of dp[][] array with 0.
- Fill the first row with 1s starting from (0, 0) till we encounter a blocked cell.
- Fill the first column with 1s starting from (0, 0) till we encounter a blocked cell.
- For all the other cells (i, j):
- If the cell is blocked, dp[i][j] = 0.
- If the cell is empty, dp[i][j] = dp[i - 1][j] + dp[i][j - 1].
- After all the iterations, return dp[N-1][N-1] as the final answer.
Below is the implementation of the algorithm:
C++
#include <bits/stdc++.h>
#define ll long long int
#define mod 1000000007
using namespace std;
ll solve(vector<string>& grid, ll N)
{
// dp[][] array such that dp[i][j] stores the number of
// ways to reach cell(i, j) from cell(0, 0)
vector<vector<ll> > dp(N, vector<ll>(N, 0));
// Finding the number of ways for the first column
for (int i = 0; i < N; i++) {
if (grid[i][0] == '*')
break;
dp[i][0] = 1;
}
// Finding the number of ways for the first row
for (int j = 0; j < N; j++) {
if (grid[0][j] == '*')
break;
dp[0][j] = 1;
}
// Finding the number of ways for the remaining grid
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
// If the cell is blocked, then move to the next
// cell
if (grid[i][j] == '*')
continue;
// The number of ways to reach cell(i, j) =
// number of ways to reach cell (i-1,j) + number
// of ways to reach cell(i,j-1)
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
}
}
// Return the number of ways to reach the last cell of the grid
return dp[N - 1][N -1];
}
int main()
{
// Sample Input
ll N = 4;
vector<string> grid = {"....", ".*..", "...*", "*..."};
cout << solve(grid, N) << "\n";
}
Java
import java.util.*;
public class Main {
// Function to find the number of ways to the reach the bottom-right cell
static long GFG(ArrayList<String> grid, int N, int mod) {
long[][] dp = new long[N][N];
// Finding the number of ways for first column
for (int i = 0; i < N; i++) {
if (grid.get(i).charAt(0) == '*')
break;
dp[i][0] = 1;
}
// Finding the number of ways for the first row
for (int j = 0; j < N; j++) {
if (grid.get(0).charAt(j) == '*')
break;
dp[0][j] = 1;
}
// Finding the number of ways for remaining grid
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
// If the cell is blocked, then move to the next cell
if (grid.get(i).charAt(j) == '*')
continue;
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
}
}
return dp[N - 1][N - 1];
}
public static void main(String[] args) {
// Input
int N = 4;
ArrayList<String> grid = new ArrayList<>(Arrays.asList("....", ".*..", "...*", "*..."));
int mod = 1000000007;
System.out.println(GFG(grid, N, mod));
}
}
C#
using System;
using System.Collections.Generic;
public class Geeks
{
// Function to find the number of ways to reach the bottom-right cell
static long GFG(List<string> grid, int N, int mod)
{
long[,] dp = new long[N, N];
// Finding the number of ways for first column
for (int i = 0; i < N; i++)
{
if (grid[i][0] == '*')
break;
dp[i, 0] = 1;
}
// Finding the number of ways for the first row
for (int j = 0; j < N; j++)
{
if (grid[0][j] == '*')
break;
dp[0, j] = 1;
}
// Finding the number of ways for remaining grid
for (int i = 1; i < N; i++)
{
for (int j = 1; j < N; j++)
{
// If the cell is blocked, then move to the next cell
if (grid[i][j] == '*')
continue;
dp[i, j] = (dp[i - 1, j] + dp[i, j - 1]) % mod;
}
}
return dp[N - 1, N - 1];
}
public static void Main(string[] args)
{
// Input
int N = 4;
List<string> grid = new List<string> { "....", ".*..", "...*", "*..." };
int mod = 1000000007;
Console.WriteLine(GFG(grid, N, mod));
}
}
JavaScript
function GFG(grid, N) {
const mod = 1000000007;
// Initialize dp array to store the number of the ways to reach each cell
const dp = Array.from({ length: N }, () => Array(N).fill(0));
for (let i = 0; i < N; i++) {
if (grid[i][0] === '*') break;
dp[i][0] = 1;
}
// Finding the number of ways for the first row
for (let j = 0; j < N; j++) {
if (grid[0][j] === '*') break;
dp[0][j] = 1;
}
// Finding the number of ways for remaining grid
for (let i = 1; i < N; i++) {
for (let j = 1; j < N; j++) {
// If the cell is blocked, then move to the next cell
if (grid[i][j] === '*') continue;
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
}
}
return dp[N - 1][N - 1];
}
// Sample Input
const N = 4;
const grid = ["....", ".*..", "...*", "*..."];
console.log(GFG(grid, N));
Python3
def GFG(grid, N):
mod = 1000000007
# Initialize dp array to store the number of the ways to reach each cell
dp = [[0]*N for _ in range(N)]
for i in range(N):
if grid[i][0] == '*':
break
dp[i][0] = 1
# Finding the number of ways for the first row
for j in range(N):
if grid[0][j] == '*':
break
dp[0][j] = 1
# Finding the number of ways for remaining grid
for i in range(1, N):
for j in range(1, N):
# If the cell is blocked, then move to the next cell
if grid[i][j] == '*':
continue
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod
return dp[N - 1][N - 1]
# Sample Input
N = 4
grid = ["....", ".*..", "...*", "*..."]
print(GFG(grid, N))
Time Complexity: O(N * N), where N is the number of rows or columns in the grid.
Auxiliary Space: O(N * N)
Similar Reads
CSES Solutions - Grid Paths
There are 88418 paths in a 7x7 grid from the upper-left square to the lower-left square. Each path corresponds to a 48-character description consisting of characters D (down), U (up), L (left) and R (right). You are given a description of a path which may also contain characters ? (any direction). Y
15 min read
CSES Solutions â Labyrinth
You are given a map of a labyrinth, and your task is to find a path from start to end. You can walk left, right, up and down. The first input line has two integers n and m: the height and width of the map. Then there are lines of m characters describing the labyrinth. Each character is . (floor), #
11 min read
CSES Solutions - Swap Game
You are given a 3X3 grid containing the numbers 1,2...9. Your task is to perform a sequence of moves so that the grid will look like this: 1 2 34 5 67 8 9On each move, you can swap the numbers in any two adjacent squares (horizontally or vertically). What is the minimum number of moves required? Exa
10 min read
CSS grid-row-gap Property
The grid-row-gap property in CSS is used to define the size of the gap between the grid elements. The user can specify the width of the gap separating the rows by providing a value to the grid-row-gap. Syntax:grid-row-gap: length | percentage | global-values;Property Values:length: The user can set
3 min read
Pure CSS Responsive Grids
Pure CSS is a free and open-source framework of CSS. CSS Grid Layout is a method designed for the two-dimensional layout of items with rows and columns. It consists of both unresponsive and responsive modules. Responsive design's function is to display the contents of the website automatically acros
4 min read
CSES Solutions - Number Spiral
A number spiral is an infinite grid whose upper-left square has the number 1. The task is to find the number in row Y and column X. Here are the first five layers of the spiral: Examples: Input:Â Y = 2, X = 3Output:Â 8Explanation: The 2nd row, 3rd column contains 8. Input:Â Y = 4, X = 2Output:Â 15Explan
9 min read
POTD Solutions | 22 Octâ 23 | Number of paths
View all POTD Solutions Welcome to the daily solutions of our PROBLEM OF THE DAY (POTD). We will discuss the entire problem step-by-step and work towards developing an optimized solution. This will not only help you brush up on your concepts of Combinatorics but will also help you build up problem-s
5 min read
What is CSS Grid?
CSS Grid is the powerful layout property in CSS that allows the web developers to design the complex and responsive grid-based layout. Unlike the older layout systems like Flexbox, which focuses on one dimensional layouts. CSS Grid is the two dimensional system, means that it can handle simultaneous
4 min read
How To Use Tailwind CSS Grid?
Tailwind CSS can provide a highly customizable and low-level framework to build responsive and dynamic web layouts using the utility-first classes. One of the most powerful layout systems provided by Tailwind is CSS Grid, which allows developers to create complex and flexible grid-based layouts with
4 min read
CSS grid-row Property
The grid-row property in CSS is used to define the size and position of a grid item within a grid layout. It combines the grid-row-start and grid-row-end properties to specify the item's start and end positions along the row axis.Syntax:grid-row: grid-row-start|grid-row-end;Property Values1. grid-ro
3 min read