using
System;
using
System.Collections.Generic;
public
class
GFG
{
static
int
[] dx = { 1, -1, 0, 0, 1, -1, 1, -1 };
static
int
[] dy = { 0, 0, 1, -1, 1, 1, -1, -1 };
static
bool
Ok(
int
X,
int
Y,
int
N,
int
M)
{
return
X >= 0 && Y >= 0 && X < N && Y < M;
}
static
int
MinCost(List<List<
int
>> A,
int
N,
int
M)
{
int
[,] dist =
new
int
[N, M];
for
(
int
i = 0; i < N; i++)
{
for
(
int
j = 0; j < M; j++)
{
dist[i, j] =
int
.MaxValue;
}
}
dist[0, 0] = 0;
var
pq =
new
PriorityQueue<Pair>((p1, p2) => p1.dist.CompareTo(p2.dist));
pq.Enqueue(
new
Pair(0, 0, 0));
while
(pq.Count > 0)
{
Pair v = pq.Dequeue();
int
curDist = v.dist;
int
curX = v.x;
int
curY = v.y;
if
(curDist > dist[curX, curY])
continue
;
for
(
int
i = 0; i < 8; i++)
{
int
newX = curX + dx[i];
int
newY = curY + dy[i];
if
(Ok(newX, newY, N, M)
&& A[newX][newY] == 0)
{
int
cost = 0;
if
(i > 3)
cost = 1;
int
newDist = curDist + cost;
if
(newDist < dist[newX, newY])
{
dist[newX, newY] = newDist;
pq.Enqueue(
new
Pair(newDist, newX, newY));
}
}
}
}
return
dist[N - 1, M - 1];
}
public
class
Pair
{
public
int
dist, x, y;
public
Pair(
int
dist,
int
x,
int
y)
{
this
.dist = dist;
this
.x = x;
this
.y = y;
}
}
public
class
PriorityQueue<T>
{
private
List<T> list;
private
Comparison<T> comparison;
public
PriorityQueue(Comparison<T> comparison)
{
this
.list =
new
List<T>();
this
.comparison = comparison;
}
public
void
Enqueue(T item)
{
list.Add(item);
int
i = list.Count - 1;
while
(i > 0)
{
int
j = (i - 1) / 2;
if
(comparison(list[i], list[j]) >= 0)
break
;
T tmp = list[i];
list[i] = list[j];
list[j] = tmp;
i = j;
}
}
public
T Dequeue()
{
int
last = list.Count - 1;
T frontItem = list[0];
list[0] = list[last];
list.RemoveAt(last);
last--;
int
parent = 0;
while
(
true
)
{
int
left = parent * 2 + 1;
if
(left > last)
break
;
int
right = left + 1;
if
(right <= last && comparison(list[right], list[left]) < 0)
left = right;
if
(comparison(list[left], list[parent]) >= 0)
break
;
T tmp = list[left];
list[left] = list[parent];
list[parent] = tmp;
parent = left;
}
return
frontItem;
}
public
int
Count {
get
{
return
list.Count; } }
}
public
static
void
Main(
string
[] args)
{
int
N = 4, M = 4;
List<List<
int
>> A =
new
List<List<
int
>>
{
new
List<
int
> {0, 0, 1, 0},
new
List<
int
> {0, 0, 1, 0},
new
List<
int
> {0, 1, 0, 0},
new
List<
int
> {0, 1, 0, 0}
};
Console.WriteLine(MinCost(A, N, M));
int
N1 = 5, M1 = 5;
List<List<
int
>> A1 =
new
List<List<
int
>>
{
new
List<
int
> {0, 0, 1, 0, 0},
new
List<
int
> {1, 0, 1, 0, 1},
new
List<
int
> {1, 1, 0, 1, 1},
new
List<
int
> {1, 0, 1, 0, 1},
new
List<
int
> {0, 0, 1, 0, 0}
};
Console.WriteLine(MinCost(A1, N1, M1));
}
}