문제 출처
1. 문제설명
n * n
격자판에서 새로운 규칙을 가진 윷놀이를 진행한다.
- 격자의 각 칸에는 흰색, 빨간색, 파란색 중 하나의 색을 갖는다.
- 말은 총
k
개가 주어지며, 격자판의 한 지점에 놓여있다.
- 1번부터 k번까지 번호가 지정되어 있으며 이동 방향 또한 미리 정해져있다.
- 상하좌우의 4가지 방향으로 움직일 수 있다.
- 윷놀이 규칙
- 이동하려는 칸이 흰색인 경우
- 해당 칸으로 이동
- 이동하려는 칸에 말이 이미 있는 경우에는 해당 말 위에 이동하려던 말을 올린다.
- 이미 말이 올려져 있는 상태에도 말을 올릴 수 있다.
- 이동하려는 칸이 빨간색인 경우
- 이동하려는 칸이 빨간색인 경우에는 해당 칸으로 이동하기 전 순서를 뒤집는다.
- 이후 해당 칸에 말이 있는 경우에는 흰색 칸과 같이 처리한다.
- 이동하려는 칸이 파란색인 경우
- 이동하지 않고 방향을 반대로 전환한 뒤 이동
- 만일 반대 방향으로 전환한 뒤 이동하려는 칸도 파란색이라면 방향만 반대로 전환한 뒤 이동하지 않고 가만히 있는다.
- 이동하려는 말에 다른 말들이 쌓여있을 경우에 이동하려는 말만 방향을 반대로 바꾼다.
- 격자판의 범위를 벗어나는 경우
2. 입/출력
- 윷놀이 판의 크기
n
- 0은 흰색 판, 1은 빨간색 판, 2는 파란색 판을 의미
- 말의 개수
k
- 위치 x, y와 방향 d
- d는 1일 경우 오른쪽, 2일 경우 왼쪽, 3일 경우 윗쪽, 4일 경우 아랫쪽
- 게임이 진행되는 동안 아직 한 턴이 다 끝나지 않은 경우더라도 말이 4개 이상 겹쳐지는 경우가 생긴다면 그 즉시 게임을 종료
- 게임이 종료되는 턴의 번호를 출력합니다. 답이 1000보다 크거나 불가능한 경우에는 -1을 출력
3. 문제 분류
4. 알고리즘 설계
- 게임 횟수를 최대 1000번으로 잡고 시뮬레이션 진행
- 각 시뮬레이션마다 말을 1번부터 순차적으로 움직인다.
- 말을 움직이는 방법
- 파란색 또는 격자 범위 밖
- 방향을 전환한다.
- 전환 후에도 파란색 또는 격자 범위 밖이면 무시된다.
- 현재 위치의 말들의 번호 순서 벡터
cur
, 다음 위치의 말들의 번호 순서 벡터 next
- 벡터의 순서가 뒤에 있을수록 위에 있음을 나타낸다.
find
함수를 통해 현재 탐색중인 i
번째 말의 벡터 인덱스를 탐색
- 인덱스부터
cur.end()
까지가 우리가 뒤짚어야할 대상이다.
- 자신의 차례에 자신 밑에 다른 말들이 있을 수 있다.
- 이때는 다음 방향으로 자신과 자신 위의 것들만 이동하기 때문이다.
- 인덱스부터
cur.end()
까지 next
에 push_back()
한다.
- 인덱스부터
cur.end()
까지의 정보를 삭제한다.
5. 전체 코드
4. 소감
- 벡터와 iterator를 잘 응용한 풀이라고 생각이 되었다.
- 아마 일일히 구현했다면 코드도 지저분해지고 실수도 많아졌을 것이다.