구현 / 시뮬레이션 문제.
처음에 어떻게 방향들을 나눌 수 있을까 고민을 많이해본 것 같다.
주사위의 주변칸들이 어떻게 구성되는지 알 수 있다면 쉽게 풀 수 있다.
그리고 이 문제를 2번 틀렸는데, 문제에서 좌표가 (x, y)로 구성돼있다.
입력도 x y순서로 입력받는데 사실 이는 y좌표와 x좌표를 순서대로 입력받는 것과 마찬가지이다.
이 부분을 고려하지 못해서 틀렸다.
문제풀이
조건에 윗 면이 1이고, 동쪽을 바라보는 방향이 3인 상태로 놓여져 있다고 되어있다.
그런데 어차피 윗면이 1이든 6이든, 모든 주사위의 칸은 처음에 0이므로 아랫면을 1로 설정하고 풀어도 상관없다.
1이든 6이든 동쪽을 바라보는 방향이 3인 것만 유지시켜주면 된다.
그리고 예제 입력 1을 예로들면
좌표는 다음과 같은 형태이다.
(0,0) | (0,1) |
(1,0) | (1,1) |
(2,0) | (2,1) |
(3,0) | (3,1) |
그런데 2차원 배열로 입력받으면 위같은 형태의 순서로 입력받기 까다롭다고 생각했다.
그래서 상하 대칭, 좌우 대칭 시켜서 풀었다. (이렇게 풀었더니 동, 서, 남, 북 좌표잡기도 복잡했다.)
그런데 생각해보니 굳이 그럴 필요가 없어서 다시 위같은 형태로 입력받고 풀었다.
그리고 주사위는 굴렸을 때 조건이 있다.
- 만일 이동한 칸의 숫자가 0이라면 주사위의 숫자를 복사한다.
- 만일 이동한 칸의 숫자가 0이 아니라면 해당 칸의 숫자를 주사위에 복사하고 해당 칸을 0으로 만든다.
- 주사위를 이동시켰을 때 주사위 상단 면의 숫자를 출력한다.
- 주사위는 바깥으로 이동시킬 수 없다.
어려운 조건들은 아니였다.
나같은 경우 위 모습의 주사위를 그려주었다.
세번째 조건은 바닥면이 [1]인 경우에는 [5]의 값을, [2]인 경우에는 [4]를, [3]인 경우에는 [6]을 ...
이런 식으로 바닥면이 마주보는 면의 숫자를 출력하도록 했다.
사실 이 문제에서 핵심은 바닥면의 주변 4칸을 어떻게 구하는지이다.
이전 칸을 알기 때문에 온 방향의 반대방향에 이전 칸이 있다고 생각하면 된다.
그리고 현재 칸 기준 온 방향에는 이전 칸의 맞은편 칸이 있다.
- 위 그림에서 [3]->[1]로 가는 것은, 북쪽으로 가는 것이다.
- 따라서 [1]을 기준으로 남쪽에는 [3]이 있고 북쪽에는 [3]의 맞은편인 [6]이 있다.
그렇다면 동쪽과 서쪽은 어떻게 구할까?
정답은 그대로이다.
- 주사위를 남, 북쪽으로 아무리 굴려도 바닥면의 동, 서쪽은 그대로가 된다.
- 반대로 동, 서쪽으로 아무리 굴려도 바닥면의 남, 북쪽은 그대로이다.
위 부분을 캐치했다면 문제를 쉽게 풀 수 있다.
코드를 살펴보자.
높이와 너비, 주사위의 Y, X좌표, 명령어의 개수를 담는 변수가 있다.
그리고 지도의 각 칸 위에 숫자를 나타내는 board 2차원 배열이 있다.
dice 배열은 주사위의 각 칸에 어떤 숫자가 있는지 기록한다.
그리고 현재 바닥면을 나타내는 curIdx 변수,
어디 방향으로 이동하는지를 나타내는 moveDirection 변수가 있다.
movePoint 배열은 동,서,북,남 방향을 기준으로 y, x좌표를 더해준다.
그리고 현재 칸의 주변 4칸의 정보를 나타내는 curAround 배열이 있다. 0번째 idx는 사용하지 않는다.
방향에 따라 주사위를 이동시킨다.
만일 해당 방향으로 갔을때, 지도의 바깥이라면 그대로 메서드를 종료한다.
바깥이 아니라면 이전 칸의 정보를 prevIdx 변수에 저장해두고 바닥면, 좌표 변수를 업데이트한다.
그리고 이동한 지도의 칸이 0일때와 아닐때에 대해 업데이트 해준다.
현재 바닥면이 마주보는 칸이 맨 위칸이므로 해당 칸을 출력해준다.
주변 4칸의 정보는 위에서 설명했듯이, 남, 북쪽으로 이동했을 때는 남, 북쪽만 바뀌고
동, 서쪽으로 이동했을 때는 동, 서쪽만 바뀐다.
getAcross는 맞은 편 칸의 idx를 return 해주는 메서드이다.
문제의 입력들을 입력받은 후에, 각 명령어 케이스마다 방향에 따라 주사위를 이동시켜준다.
처음에 Y, X좌표를 반대로 써서 틀렸다.
그리고 바꿔서 바로 맞췄는데 너무 복잡하게 지도를 입력받는 것 같아서 바꾸다가 한번 더 틀렸다.
그런데 결국에는 방향도 맞추고 배열도 잘 맞추도록 고쳤다.
구현 / 시뮬레이션 문제는 얼마나 고민해보고 그려보는지가 중요한 것 같다.
코드 전문은 위에서 확인 가능하다.
'알고리즘 > Baekjoon' 카테고리의 다른 글
[C++] 백준 16236번 아기 상어 (0) | 2021.08.26 |
---|---|
[C++] 백준 11048번 이동하기 (0) | 2021.08.26 |
[C++] 백준 2580번 스도쿠 (6) | 2021.08.24 |
[C++] 2294번 동전 2 (0) | 2021.08.24 |
[C++] 백준 1699번 제곱수의 합 (4) | 2021.08.24 |