수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
from
배열을 만들었다.from
배열의 i
번째 인덱스에는 해당 정점에 오기 직전의 정점 번호가 기재된다.#include <iostream>
#include <queue>
using namespace std;
static constexpr int MAX = 100001;
static int subin, brother, map[MAX], from[MAX], dist[MAX];
static bool isVisited[MAX];
void backTracking(int subin, int pos) {
// subin (출발지점) 까지 백트랙킹 한다.
if (subin != pos) backTracking(subin, from[pos]);
cout << pos << ' ';
}
void solve() {
queue<int> q;
q.push(subin);
isVisited[subin] = true;
dist[subin] = 0;
while(!q.empty()) {
int pos = q.front(); q.pop();
int goPos = pos + 1, backPos = pos - 1, telePos = pos * 2;
// 한 칸 앞으로 전진하는 경우
if (goPos < MAX && isVisited[goPos] == 0) {
q.push(goPos);
isVisited[goPos] = true;
dist[goPos] = dist[pos] + 1;
from[goPos] = pos;
}
// 한 칸 뒤로 후진하는 경우
if (backPos >= 0 && isVisited[backPos] == 0) {
q.push(backPos);
isVisited[backPos] = true;
dist[backPos] = dist[pos] + 1;
from[backPos] = pos;
}
// 2배 앞으로 순간이동 하는 경우
if (pos != 0 && telePos < MAX && isVisited[telePos] == 0) {
q.push(telePos);
isVisited[telePos] = true;
dist[telePos] = dist[pos] + 1;
from[telePos] = pos;
}
}
cout << dist[brother] << '\n';
backTracking(subin, brother);
cout << '\n';
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> subin >> brother;
solve();
}
0 5
를 입력하면 메모리 초과가 나는 경우일 것이다.isVisited
배열을 구현하지 않았거나, dist
배열의 초기값이 -1
이 아니라 0
이라면 0 5
테스트 케이스에서 from
배열을 아래와 같이 나온다.dist
배열의 초기값을 -1
로 memset()
한 뒤 방문 여부를 -1
값으로 판단하거나, isVisited
배열을 구현하거나, 둘 중 편한 방법을 꼭 사용하자.