알고리즘 :: 백준 :: BFS :: 1697 :: 숨바꼭질 (velog.io) 문제의 연장입니다.
track
을 만듭니다. 이 배열이 i
번째 인덱스에는 i
에 오기 직전 위치를 기록합니다.10
에서 한 칸 뒤로 와서 9
로 왔다면, track[9] = 10
입니다.5
에서 순간이동해서 10
으로 왔다면, track[10] = 5
입니다.visited[]
배열을 이용해서 임의의 위치의 방문 여부를 체크하기 때문에 track[i]
에 들어있는 정보를 신뢰할 수 있습니다. track[i]
는 단 한 번만 저장됩니다. 5
에서 순간이동해서 10
을 왔을 때 track[10] = 5
이고,11
에서 한 칸 뒤로가려 할 때 10
은 이미 방문한 점이므로 뒤로가지 않습니다.track[10] = 5
라는 정보는 언제나 신뢰할 수 있습니다.K
에 도착했다면 이제 K
부터 track[K]
를 따라가며 값을 출력하면 됩니다.#include <iostream>
#include <vector>
#include <queue>
#define MAX 100001
using namespace std;
int N, K, track[MAX];
bool visited[MAX];
// 재귀여도 최대 20~30번 돌기 때문에 빠릅니다.
void traceTrack(int s, int e) {
if (s != e) traceTrack(s, track[e]);
cout << e << ' ';
}
void solve() {
queue<pair<int, int>> q;
q.push({N, 0});
visited[N] = true;
int ans = 0;
while (!q.empty()) {
int cPos = q.front().first, cSec = q.front().second;
if (cPos == K){ ans = cSec; break; }
q.pop();
int nPos1 = cPos * 2, nPos2 = cPos - 1, nPos3 = cPos + 1, nSec = cSec + 1;
if (nPos1 < MAX && !visited[nPos1])
q.push({nPos1, nSec}), visited[nPos1] = true, track[nPos1] = cPos;
if (nPos2 >= 0 && !visited[nPos2])
q.push({nPos2, nSec}), visited[nPos2] = true, track[nPos2] = cPos;
if (nPos3 < MAX && !visited[nPos3])
q.push({nPos3, nSec}), visited[nPos3] = true, track[nPos3] = cPos;
}
cout << ans << '\n';
traceTrack(N, K);
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> N >> K;
if (N > K) {
cout << N - K << '\n';
for (int i = N; i >= K; --i) cout << i << ' ';
return 0;
}
solve();
}