// C# implementation of above approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
// Global variables for grid, minDistance and visited
// array
static class Globals {
// global int
public static int row = 5;
public static int col = 5;
// Global variables for grid, minDistance and
// visited array
public static int[, ] minDistance
= new int[row + 1, col + 1];
public static int[, ] visited
= new int[row + 1, col + 1];
// Queue for BFS
public static Queue<KeyValuePair<int, int> > que
= new Queue<KeyValuePair<int, int> >();
}
// Function to find whether the move is valid or not
static bool isValid(int[, ] grid, int i, int j)
{
if (i < 0 || j < 0 || j >= Globals.col
|| i >= Globals.row || grid[i, j] != 0
|| Globals.visited[i, j] != 0)
return false;
return true;
}
// Function to return the minimum distance
// from source to the end of the grid
static int minDistance1(int[, ] grid, int sourceRow,
int sourceCol)
{
// If source is one of the destinations
if ((sourceCol == 0 && sourceRow == 0)
|| (sourceCol == Globals.col - 1
&& sourceRow == 0)
|| (sourceCol == 0
&& sourceRow == Globals.row - 1)
|| (sourceCol == Globals.col - 1
&& sourceRow == Globals.row - 1))
return 0;
// Set minimum value
int minFromSource = Globals.row * Globals.col;
// Precalculate minDistance of each grid with R * C
for (int i = 0; i < Globals.row; i++)
for (int j = 0; j < Globals.col; j++)
Globals.minDistance[i, j]
= Globals.row * Globals.col;
// Insert source position in queue
Globals.que.Enqueue(new KeyValuePair<int, int>(
sourceRow, sourceCol));
// Update minimum distance to visit source
Globals.minDistance[sourceRow, sourceCol] = 0;
// Set source to visited
Globals.visited[sourceRow, sourceCol] = 1;
// BFS approach for calculating the minDistance
// of each cell from source
while (Globals.que.Count > 0) {
// Iterate over all four cells adjacent
// to current cell
KeyValuePair<int, int> cell
= Globals.que.Dequeue();
// Initialize position of current cell
int cellRow = cell.Key;
int cellCol = cell.Value;
// Cell below the current cell
if (isValid(grid, cellRow + 1, cellCol)) {
// Push new cell to the queue
Globals.que.Enqueue(
new KeyValuePair<int, int>(cellRow + 1,
cellCol));
// Update one of its neighbor's distance
Globals.minDistance[cellRow + 1, cellCol]
= Math.Min(
Globals.minDistance[cellRow + 1,
cellCol],
Globals.minDistance[cellRow,
cellCol]
+ 1);
Globals.visited[cellRow + 1, cellCol] = 1;
}
// Above the current cell
if (isValid(grid, cellRow - 1, cellCol)) {
Globals.que.Enqueue(
new KeyValuePair<int, int>(cellRow - 1,
cellCol));
Globals.minDistance[cellRow - 1, cellCol]
= Math.Min(
Globals.minDistance[cellRow - 1,
cellCol],
Globals.minDistance[cellRow,
cellCol]
+ 1);
Globals.visited[cellRow - 1, cellCol] = 1;
}
// Right cell
if (isValid(grid, cellRow, cellCol + 1)) {
Globals.que.Enqueue(
new KeyValuePair<int, int>(
cellRow, cellCol + 1));
Globals.minDistance[cellRow, cellCol + 1]
= Math.Min(
Globals.minDistance[cellRow,
cellCol + 1],
Globals.minDistance[cellRow,
cellCol]
+ 1);
Globals.visited[cellRow, cellCol + 1] = 1;
}
// Left cell
if (isValid(grid, cellRow, cellCol - 1)) {
Globals.que.Enqueue(
new KeyValuePair<int, int>(
cellRow, cellCol - 1));
Globals.minDistance[cellRow, cellCol - 1]
= Math.Min(
Globals.minDistance[cellRow,
cellCol - 1],
Globals.minDistance[cellRow,
cellCol]
+ 1);
Globals.visited[cellRow, cellCol - 1] = 1;
}
}
// Minimum distance to the corner
// of the first row, first column
minFromSource = Math.Min(minFromSource,
Globals.minDistance[0, 0]);
// Minimum distance to the corner
// of the last row, first column
minFromSource = Math.Min(
minFromSource,
Globals.minDistance[Globals.row - 1, 0]);
// Minimum distance to the corner
// of the last row, last column
minFromSource = Math.Min(
minFromSource,
Globals.minDistance[Globals.row - 1,
Globals.col - 1]);
// Minimum distance to the corner
// of the first row, last column
minFromSource = Math.Min(
minFromSource,
Globals.minDistance[0, Globals.col - 1]);
// If no path exists
if (minFromSource == Globals.row * Globals.col)
return -1;
// Return the minimum distance
return minFromSource;
}
// Driver Code
static void Main()
{
int sourceRow = 3, sourceCol = 3;
int[, ] grid = { { 1, 1, 1, 0, 0 },
{ 0, 0, 1, 0, 1 },
{ 0, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 1, 1, 0, 1, 0 } };
Console.WriteLine(
minDistance1(grid, sourceRow, sourceCol));
}
}
// The code is contributed by Gautam goel (gautamgoel962)