동생의 위치가 매 초마다 정방향으로 움직인다는 특수성 때문에 고려해야할 새로운 경우의 수가 생깁니다.
바로 가만히 있는게 빠를 수도 있다는 것입니다.
17 5
의 경우17 -> 16 -> 15 -> 16 -> 15
로 좌표 16, 15에서 ±1로 왔다갔다해서 제자리에 있으면 동생은 5 -> 6 -> 8 -> 11 -> 15
로 4초 뒤 좌표 15에 도달합니다.위 경우의 수를 고려하려면 어떻게 해야 할까요? 시간을 홀수/짝수로 나눠 생각해보는 겁니다.
결과적으로 동생이 갈 수 있는 어떤 좌표 X에 대해
이번에는 방문기록 배열을 visited[2][500'001]
짜리 2차원 배열로 생성합니다. 왜냐하면, 같은 좌표 X라도 홀수번째 초에 도착했을 때와 짝수번째 초에 도착했을 때를 다르게 생각해야 하기 때문입니다.
BFS 종료조건은 어떻게 될까요?
visited[next_x] = visited[now_x] + 1
은 visited[홀수/짝수초][next_x] = visited[짝수/홀수초][now_x] + 1
이 되겠죠?#include <iostream>
#include <queue>
using namespace std;
constexpr int MAX = 500'001;
int N, K, visited[2][MAX];
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> N >> K;
if (N == K) { cout << 0; return 0; }
queue<int> q;
q.push(N);
visited[0][N] = 1;
int t = 1; // time;
bool is_they_meet = false;
while (!q.empty()) {
K += t;
if (K >= MAX) break;
if (visited[t & 1][K]) { is_they_meet = true; break; }
int qsize = q.size();
for (int i = 0; i < qsize; i++) {
int here = q.front(); q.pop();
for (int there : {here * 2, here + 1, here - 1}) {
if (there < 0 || there >= MAX || visited[t & 1][there]) continue;
if (there == K) { is_they_meet = true; break; }
visited[t & 1][there] = visited[(t + 1) & 1][here] + 1;
q.push(there);
}
if (is_they_meet) break;
}
if (is_they_meet) break;
t++;
}
(is_they_meet) ? (cout << t) : (cout << -1);
return 0;
}
t & 1
은 비트연산을 이용한 홀수, 짝수 판별법입니다.1
이고, 짝수는 항상0
이므로 1
과 AND 연산한 결과로 홀수 짝수를 판별할 수 있습니다.