문제 출처
1. 문제설명
- 수빈이는 현재 점 N(0 ≤ N ≤ 500,000)에 있고, 동생은 점 K(0 ≤ K ≤ 500,000)에 있다.
- 수빈이는 걷거나 순간이동을 할 수 있다.
- 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동
- 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동
- 동생은 항상 매 초마다 이동을 하며, 이동은 가속이 붙는다. 동생이 이동하는 거리는 이전에 이동한 거리보다 1을 더한 만큼 이동
2. 알고리즘 설계
- 이전 숨바꼭질 문제에 대비해 시간 제한이 0.25초로 줄어들었다.
- 또한 동생이 매초마다 이동을 하기 때문에 만나지 못하는 경우가 생길 수 있다.
- 이 문제는 일반적인 BFS 접근으로는 해결할 수 없었다.
- 수빈이가 짝수초에 접근한 위치는 짝수초에 또 방문할 수 있다.
- 마찬가지로 홀수초에 접근한 위치는 홀수초에 또 방문할 수 있다.
- 따라서 다음과 같이 2차원 배열로 최초 방문 시간을 체크 해준다
visited[SZ + 1][2]
- 0번째 위치는 짝수초, 1번째 위치는 홀수초 방문을 의미
- 동생의 이동시간은 현재 수빈이가 소모한 시간(
time
)으로 계산가능하다.
K + time * (time + 1) / 2
3. 전체 코드
4. 소감
- 진짜 역대급 난이도의 BFS 문제였다.
- 추가로, 매우 아름다운 구현법을 발견했다.
for (int next : {now - 1, now + 1, 2 * now})
- 기존에는 next를 일일히 초기화 시켜줬다면,
- 이 방법은 한줄로 여러 코드를 재작성하지 않아도 된다!