<aside> 💡 BFS로 풀 수 있는 문제라는 사실을 처음에 떠올리기 쉽지 않은 것 같다.
</aside>
<aside> 💡 어떻게 이동해야 최소이동 경로인지 역으로 알아내는 아이디어가 필요했다. → visited에 이전 위치를 적어서, visited를 따라가는 식으로 거꾸로 경로를 찾아갔다. → 타잔인가 코사라주 알고리즘과 비슷한 아이디어?
</aside>
// <https://www.acmicpc.net/problem/13913>
#include <bits/stdc++.h>
using namespace std;
#define fastio cin.tie(0)->sync_with_stdio(0)
#define endl '\\n';
using tp = tuple<int, int, int>;
using pp = pair<int, int>;
using ll = long long;
#define MAX 300000
int N, K;
int visited[MAX];
vector<int> v;
void solve()
{
memset(visited, -1, sizeof(visited));
queue<pp> q;
visited[N] = N;
q.push({N, 0}); // 현재 위치, 시간
while (!q.empty())
{
auto [cur, t] = q.front();
q.pop();
if (cur == K)
{
for (int before = cur; before != N; before = visited[before])
{
v.push_back(before);
}
v.push_back(N);
reverse(v.begin(), v.end());
cout << t << endl;
for (int i : v)
{
cout << i << " ";
}
return;
}
// move
int nextT = t + 1;
if (visited[cur + 1] == -1)
{
visited[cur + 1] = cur;
q.push({cur + 1, nextT});
}
if (cur - 1 >= 0 && visited[cur - 1] == -1)
{
visited[cur - 1] = cur;
q.push({cur - 1, nextT});
}
if ((cur << 1) < MAX && visited[cur << 1] == -1)
{
visited[cur << 1] = cur;
q.push({cur << 1, nextT});
}
}
}
int main()
{
fastio;
cin >> N >> K;
solve();
return 0;
}