[백준] 13460번 - 구슬 탈출2
요구사항을 정확히 코드로 옮기는 능력을 요구하는 시뮬레이션 문제이다.
난 이러한 문제를 풀 때 맵으로 주어지는 n,m의 최대 크기를 확인해보고, 이 크기가 작다면 브루트포스로 접근하는 편이다. 이 문제는 n,m이 10이하이므로 충분히 브루트포스로 풀이할 수 있다고 생각했다.
이 문제의 핵심은 크게 3가지로 구분할 수 있다.
- 구슬은 벽을 만나거나 다른 구슬을 만나거나, 구멍에 들어갈 때 까지 한 턴에 한 쪽 방향으로만 이동한다.
- 파란 구슬이 구멍에 들어가면 안된다.
- 두 구슬이 같은 행이나 열에 존재할 경우, 어떠한 구슬을 먼저 이동시키느냐가 이동 결과에 영향을 미칠 수 있다.
예를 들어, 두 구슬이 같은 행에 위치하고 두 구슬 사이에 벽이 없으며, 빨간 구슬이 파란 구슬보다 오른쪽에 있을 때 보드를 오른쪽으로 기울이는 상황을 가정해보자. 코드에서 파란 구슬을 먼저 움직인다면 파란 구슬은 중간에 빨간 구슬에 막혀 멈추게 되고, 빨간 구슬은 벽을 만날 때 까지 오른쪽으로 움직인다. 하지만 이 결과는 잘못된 결과이며, 파란 구슬과 빨간 구슬은 오른쪽 벽에 나란히 붙어 있어야 한다. 이러한 상황을 방지하기 위해 두 구슬이 같은 열, 같은 행에 있을 때 움직이는 방향에 따라 어떤 구슬을 먼저 움직일지 분기점을 나누어 주어야 한다.
이 핵심을 바탕으로 구현한 방식은 아래와 같다.
- 두 구슬의 위치를 저장하는 구조체(MARBLE_POS)를 선언하고, 이를 이용한 bfs 알고리즘을 사용한다.
- bfs 알고리즘에 필요한 visited 배열은 두 구슬의 위치를 기반으로 나타낼 수 있다. 예를 들어, 빨간 구슬이 (1,1) 위치이고, 파란 구슬이 (1,2) 위치라면
visited[1][1][1][2] = true;
로 표기한다. 구슬의 위치 이외의 맵의 다른 요소들은 위치가 항상 동일하므로 구슬의 위치만으로 방문 여부를 나타내는 것이 가능하다. - MARBLE_POS의 cnt가 11 이상일 경우 -1을 출력한다.
구현한 코드는 아래와 같다.
1 |
|