https://www.acmicpc.net/problem/13913
13913번: 숨바꼭질 4
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일
www.acmicpc.net
문제 설명
수빈이는 현재 점 N에 있고, 동생은 점 M에 있다.
수빈이의 위치가 X일 때, X + 1, X - 1, X * 2의 위치로 이동할 수 있다.
이동할 때에는 1초가 걸리며, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구한다.
또한, 어떻게 이동해야 하는지 경로를 출력한다.
N, M (1 <= N, M <= 100,000)
해결
간단한 BFS에 경로 출력이 더해진 문제이다.
최단 거리는 BFS를 통해 구해 준다.
BFS를 통해 거리를 찾을 때, parent 배열에 어디 숫자로부터 도착했는지 각각 저장해 준다.
동생의 위치에 도달했을 때 parent배열을 동생의 위치부터 수빈이의 위치까지 역추적하며 vector에 경로를 저장한다.
N과 M이 같을 때와, N이 M보다 더 클 때는 예외처리 해 주었다.
N이 M보다 클 때는 수빈이가 X - 1의 연산으로밖에 이동할 수 없으므로 따로 예외처리 해 주어 더 빠른 시간 내로 도달할 수 있도록 하였다.
코드
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
int n, m;
int visited[200002];
int parent[200002];
vector<int> v;
void bfs() {
queue<int> q;
q.push(n);
visited[n] = 1;
while (!q.empty()) {
auto cur = q.front(); q.pop();
for (auto a : { cur + 1, cur - 1, cur * 2 }) {
if (a < 0 || a > 200005) continue;
if (visited[a]) continue;
visited[a] = visited[cur] + 1;
parent[a] = cur;
if (a == m) {
int idx = a;
for (int i = 0; i < visited[a]; i++) {
v.push_back(idx);
idx = parent[idx];
}
return;
}
q.push(a);
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
if (n == m) {
cout << 0 << "\n" << n;
return 0;
}
if (m < n) {
cout << n - m << "\n";
for (int i = n; i >= m; i--)
cout << i << " ";
return 0;
}
bfs();
cout << visited[m] - 1 << "\n";
for (int i = v.size() - 1; i >= 0; i--)
cout << v[i] << " ";
}
'백준' 카테고리의 다른 글
[백준/c++] BOJ 5558 - チーズ (Cheese) (0) | 2023.10.12 |
---|---|
[백준/c++] BOJ 14496 - 그대, 그머가 되어 (0) | 2023.10.05 |
[백준/c++] BOJ 14226 - 이모티콘 (1) | 2023.10.01 |
[백준/c++] BOJ 14923 - 미로 탈출 (1) | 2023.10.01 |
[백준/c++] BOJ 16173 - 점프왕 쩰리 (Small) (0) | 2023.09.28 |