[코딩테스트] 23/12/10 - 미로 찾기 (Level2)
문제 설명
1 x 1 크기의 칸들로 이루어진 직사각형 격자 형태의 미로에서 탈출하려고 합니다. 각 칸은 통로 또는 벽으로 구성되어 있으며, 벽으로 된 칸은 지나갈 수 없고 통로로 된 칸으로만 이동할 수 있습니다. 통로들 중 한 칸에는 미로를 빠져나가는 문이 있는데, 이 문은 레버를 당겨서만 열 수 있습니다. 레버 또한 통로들 중 한 칸에 있습니다. 따라서, 출발 지점에서 먼저 레버가 있는 칸으로 이동하여 레버를 당긴 후 미로를 빠져나가는 문이 있는 칸으로 이동하면 됩니다. 이때 아직 레버를 당기지 않았더라도 출구가 있는 칸을 지나갈 수 있습니다. 미로에서 한 칸을 이동하는데 1초가 걸린다고 할 때, 최대한 빠르게 미로를 빠져나가는데 걸리는 시간을 구하려 합니다.
미로를 나타낸 문자열 배열 maps가 매개변수로 주어질 때, 미로를 탈출하는데 필요한 최소 시간을 return 하는 solution 함수를 완성해주세요. 만약, 탈출할 수 없다면 -1을 return 해주세요.
제한사항
- 5 ≤
maps의 길이 ≤ 100- 5 ≤
maps[i]의 길이 ≤ 100 maps[i]는 다음 5개의 문자들로만 이루어져 있습니다.- S : 시작 지점
- E : 출구
- L : 레버
- O : 통로
- X : 벽
- 시작 지점과 출구, 레버는 항상 다른 곳에 존재하며 한 개씩만 존재합니다.
- 출구는 레버가 당겨지지 않아도 지나갈 수 있으며, 모든 통로, 출구, 레버, 시작점은 여러 번 지나갈 수 있습니다.
- 5 ≤
문제풀이
- BFS를 두번사용한다.
- 시작점에서 레버가기
- 레버에서 출구 가기
코드 (C++)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
struct Pos
{
int x;
int y;
int curTime;
};
bool FindRoot(vector<string> maps, Pos Start, Pos End, int dr[], int dc[], int& value)
{
queue<Pos> s;
Start.curTime = value;
s.push(Start);
Pos Goal = End;
int mapSizeY = maps.size();
int mapSizeX = maps[mapSizeY - 1].size();
vector<vector<bool>> visited(mapSizeY, vector<bool>(mapSizeX, false));
while (!s.empty())
{
Pos curPos = s.front();
s.pop();
if (curPos.x == Goal.x && curPos.y == Goal.y)
{
value = curPos.curTime;
return true;
}
for (int i = 0; i < 4; ++i)
{
int nx = curPos.x + dr[i];
int ny = curPos.y + dc[i];
if (!(ny < maps.size() && nx < maps[ny].size() && maps[ny][nx] != 'X' && !visited[ny][nx]))
{
continue;
}
Pos newPos;
newPos.x = nx;
newPos.y = ny;
visited[ny][nx] = true;
newPos.curTime = curPos.curTime + 1;
s.push(newPos);
}
}
return false;
}
int solution(vector<string> maps) {
int answer = 0;
Pos Lever;
Pos Start;
Pos End;
int dr[] = {1, -1, 0, 0};
int dc[] = {0, 0, 1, -1};
for (int i = 0; i < maps.size(); ++i)
{
for (int j = 0; j < maps[i].size(); ++j)
{
if (maps[i][j] == 'L')
{
Lever.x = j;
Lever.y = i;
Lever.curTime = 0;
}
if (maps[i][j] == 'E')
{
End.x = j;
End.y = i;
End.curTime = 0;
}
if (maps[i][j] == 'S')
{
Start.x = j;
Start.y = i;
Start.curTime = 0;
}
}
}
if (!FindRoot(maps, Start, Lever, dr, dc, answer))
return -1;
if (!FindRoot(maps, Lever, End, dr, dc, answer))
return -1;
return answer;
}
This post is licensed under CC BY 4.0 by the author.