using
System;
using
System.Collections.Generic;
public
class
MainClass {
const
int
MAXN = 105;
const
int
INF = 0x3f3f3f3f;
static
char
[, ] maze =
new
char
[MAXN, MAXN];
static
int
n, m;
static
int
[] distanceFromStart =
new
int
[MAXN * MAXN];
static
int
[] distanceFromRat1 =
new
int
[MAXN * MAXN];
static
int
[] distanceFromRat2 =
new
int
[MAXN * MAXN];
static
bool
[, ] visited =
new
bool
[MAXN, MAXN];
static
List<
int
> unlockedCells =
new
List<
int
>();
static
Queue<
int
> Q =
new
Queue<
int
>();
static
readonly
int
[, ] step
= { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
static
void
Dfs(
int
x,
int
y,
int
d,
int
[] distance)
{
for
(
int
i = 0; i < 4; i++) {
int
u = x + step[i, 0];
int
v = y + step[i, 1];
if
(u >= 0 && v >= 0 && u < n && v < m
&& !visited[u, v] && maze[u, v] !=
'*'
&& maze[u, v] !=
'$'
) {
distance[m * u + v] = d;
visited[u, v] =
true
;
if
(maze[u, v] ==
'#'
) {
distance[m * u + v]++;
Q.Enqueue(m * u + v);
}
else
{
Dfs(u, v, d, distance);
}
}
}
}
static
void
Bfs(
int
[] distance)
{
while
(Q.Count > 0) {
int
p = Q.Dequeue();
int
x = p / m, y = p % m;
Dfs(x, y, distance[m * x + y], distance);
}
}
public
static
void
Main()
{
int
T = 1;
while
(T-- > 0) {
n = 5;
m = 9;
char
[, ] inputMaze
= { {
'*'
,
'*'
,
'*'
,
'*'
,
'#'
,
'*'
,
'*'
,
'*'
,
'*'
},
{
'*'
,
'.'
,
'.'
,
'#'
,
'.'
,
'#'
,
'.'
,
'.'
,
'*'
},
{
'*'
,
'*'
,
'*'
,
'*'
,
'.'
,
'*'
,
'*'
,
'*'
,
'*'
},
{
'*'
,
'$'
,
'#'
,
'.'
,
'#'
,
'.'
,
'#'
,
'$'
,
'*'
},
{
'*'
,
'*'
,
'*'
,
'*'
,
'*'
,
'*'
,
'*'
,
'*'
,
'*'
} };
for
(
int
i = 0; i < n; i++) {
for
(
int
j = 0; j < m; j++) {
maze[i, j] = inputMaze[i, j];
}
}
Array.Fill(distanceFromStart, INF);
Array.Fill(distanceFromRat1, INF);
Array.Fill(distanceFromRat2, INF);
for
(
int
i = 0; i < MAXN; i++) {
for
(
int
j = 0; j < MAXN; j++) {
visited[i, j] =
false
;
}
}
unlockedCells.Clear();
bool
isRat1Found =
false
;
int
rat1Pos = 0, rat2Pos = 0;
for
(
int
i = 0; i < n; i++) {
for
(
int
j = 0; j < m; j++) {
if
((i == 0 || j == 0 || i == n - 1
|| j == m - 1)
&& (maze[i, j] ==
'.'
|| maze[i, j] ==
'$'
)) {
Q.Enqueue(m * i + j);
distanceFromStart[m * i + j] = 0;
visited[i, j] =
true
;
}
}
}
for
(
int
i = 0; i < n; i++) {
for
(
int
j = 0; j < m; j++) {
if
(maze[i, j] ==
'*'
)
continue
;
if
((i == 0 || j == 0 || i == n - 1
|| j == m - 1)
&& maze[i, j] ==
'#'
) {
distanceFromStart[m * i + j] = 1;
Q.Enqueue(m * i + j);
visited[i, j] =
true
;
}
if
(maze[i, j] ==
'#'
)
unlockedCells.Add(m * i + j);
if
(maze[i, j] ==
'$'
) {
if
(!isRat1Found) {
rat1Pos = m * i + j;
distanceFromRat1[rat1Pos] = 0;
isRat1Found =
true
;
}
else
{
rat2Pos = m * i + j;
distanceFromRat2[rat2Pos] = 0;
}
}
}
}
Bfs(distanceFromStart);
for
(
int
i = 0; i < MAXN; i++)
for
(
int
j = 0; j < MAXN; j++)
visited[i, j] =
false
;
visited[rat1Pos / m, rat1Pos % m] =
true
;
Q.Enqueue(rat1Pos);
Bfs(distanceFromRat1);
for
(
int
i = 0; i < MAXN; i++)
for
(
int
j = 0; j < MAXN; j++)
visited[i, j] =
false
;
visited[rat2Pos / m, rat2Pos % m] =
true
;
Q.Enqueue(rat2Pos);
Bfs(distanceFromRat2);
int
ans = distanceFromStart[rat1Pos]
+ distanceFromStart[rat2Pos];
for
(
int
i = 0; i < unlockedCells.Count; i++) {
ans = Math.Min(
ans,
distanceFromRat1[unlockedCells[i]]
+ distanceFromRat2[unlockedCells[i]]
+ distanceFromStart
[unlockedCells[i]]
- 2);
}
Console.WriteLine(ans);
}
}
}