// C# program to find out path in
// a rectangle containing circles.
using System;
using System.Collections;
using System.Collections.Generic;
class HelloWorld {
// Function to find out if there is
// any possible path or not.
public static bool isPossible(int m, int n, int k, int r, int[] X, int [] Y)
{
// Take an array of m*n size and
// initialize each element to 0.
int[,] rect = new int[m, n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
rect[i,j] = 0;
}
}
// Now using Pythagorean theorem find if a
// cell touches or within any circle or not.
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
for (int p = 0; p < k; p++) {
if (Math.Sqrt((Math.Pow((X[p] - 1 - i), 2) + Math.Pow((Y[p] - 1 - j), 2))) <= r) {
rect[i,j] = -1;
}
}
}
}
// If the starting cell comes within
// any circle return false.
if (rect[0,0] == -1)
return false;
// Now use BFS to find if there
// is any possible path or not.
// Initialize the queue which holds
// the discovered cells whose neighbors
// are not discovered yet.
Queue<KeyValuePair<int, int>> qu = new Queue<KeyValuePair<int, int>>();
rect[0,0] = 1;
qu.Enqueue(new KeyValuePair<int, int>(0, 0));
// Discover cells until queue is not empty
while (qu.Count > 0) {
var arr = qu.Dequeue();
int elex = arr.Key;
int eley = arr.Value;
// Discover the eight adjacent nodes.
// check top-left cell
if ((elex > 0) && (eley > 0) && (rect[elex - 1,eley - 1] == 0)) {
rect[elex - 1,eley - 1] = 1;
qu.Enqueue(new KeyValuePair<int, int>(elex - 1, eley - 1));
}
// check top cell
if ((elex > 0) && (rect[elex - 1,eley] == 0)) {
rect[elex - 1,eley] = 1;
qu.Enqueue(new KeyValuePair<int, int>(elex - 1, eley));
}
// check top-right cell
if ((elex > 0) && (eley < n - 1) && (rect[elex - 1,eley + 1] == 0)) {
rect[elex - 1,eley + 1] = 1;
qu.Enqueue(new KeyValuePair<int, int>(elex - 1, eley + 1));
}
// check left cell
if ((eley > 0) && (rect[elex,eley - 1] == 0)) {
rect[elex,eley - 1] = 1;
qu.Enqueue(new KeyValuePair<int, int>(elex, eley - 1 ));
}
// check right cell
if ((eley < n - 1) && (rect[elex,eley + 1] == 0)) {
rect[elex,eley + 1] = 1;
qu.Enqueue(new KeyValuePair<int, int>(elex, eley + 1 ));
}
// check bottom-left cell
if ((elex < m - 1) && (eley > 0) && (rect[elex + 1,eley - 1] == 0)) {
rect[elex + 1,eley - 1] = 1;
qu.Enqueue(new KeyValuePair<int, int>(elex + 1,eley - 1));
}
// check bottom cell
if ((elex < m - 1) && (rect[elex + 1,eley] == 0)) {
rect[elex + 1,eley] = 1;
qu.Enqueue(new KeyValuePair<int, int>(elex + 1,eley));
}
// check bottom-right cell
if ((elex < m - 1) && (eley < n - 1) && (rect[elex + 1,eley + 1] == 0)) {
rect[elex + 1,eley + 1] = 1;
qu.Enqueue(new KeyValuePair<int, int>(elex + 1,eley + 1));
}
}
// Now if the end cell (i.e. bottom right cell)
// is 1(reachable) then we will send true.
return (rect[m - 1,n - 1] == 1);
}
static void Main() {
// Test case 1
int m1 = 5, n1 = 5, k1 = 2, r1 = 1;
int[] X1 = { 1, 3 };
int[] Y1 = { 3, 3 };
// Function call
if (isPossible(m1, n1, k1, r1, X1, Y1))
Console.WriteLine("Possible");
else
Console.WriteLine("Not Possible");
// Test case 2
int m2 = 5, n2 = 5, k2 = 2, r2 = 1;
int[] X2 = { 1, 1 };
int[] Y2 = { 2, 3 };
// Function call
if (isPossible(m2, n2, k2, r2, X2, Y2))
Console.WriteLine("Possible");
else
Console.WriteLine("Not Possible");
}
}
// The code is contributed by Nidhi goel.