https://www.acmicpc.net/problem/13913
13913번: 숨바꼭질 4
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일
www.acmicpc.net
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
첫째 줄에 수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
둘째 줄에 어떻게 이동해야 하는지 공백으로 구분해 출력한다.
5 17
4
5 10 9 18 17
5 17
4
5 4 8 16 17
좀 고민할 시간이 필요하긴 했지만, 쉬운 문제였다!
이건 간단하게 했다.
next[0] = now + 1;
next[1] = now - 1;
next[2] = now * 2;
이후 for문으로 next배열을 하나씩 순회하며 해당 위치에 시간 +1을 해주면 된다.
지금까지 코딩을 할 때, 어떤 경로로 이동했는지는 보통 dfs로 기록했기 때문에 헷갈렸다. dfs도 써야하는 건가? 말이 안되는데? 고민하다가.. bfs의 장점을 문득 떠올렸다. 해당 장소에 도착했을 때 그 때가 무조건 최솟값인 bfs. 그럼 해당 장소에 도착하지 전 장소를 기억하면 된다. 간단한 문제였다.
route배열을 두고, route[next[i]] = now; 로 이전 경로를 기록했다.
이후
int nowRoute = K;
vector<int> realRoute;
realRoute.push_back(K);
for (int i = 0; i < visited[K]; ++i)
{
realRoute.push_back(route[nowRoute]);
nowRoute = route[nowRoute];
}
를 해주면, 경로대로 realRoute 배열에 삽입이 될 것이다.
#include <iostream>
#include <vector>
#include <queue>
#define SIZE 100001
#define endl '\n'
using namespace std;
int N, K; // 수빈이의 위치, 동생의 위치
vector<int> visited; // 방문여부 체크, 도착하는데 걸린 시간
vector<int> route; // 각 인덱스마다, 이전의 경로를 저장
void bfs(int start)
{
visited[start] = 0;
queue<int> bfsq;
bfsq.push(start);
int next[3];
while (!bfsq.empty())
{
int now = bfsq.front();
bfsq.pop();
if (now == K)
return;
next[0] = now + 1;
next[1] = now - 1;
next[2] = now * 2;
for (int i = 0; i < 3; ++i)
{
if (next[i] >= SIZE || next[i] < 0) // 칸이 유효한지 확인
continue;
if (visited[next[i]] == -1) // 방문한 적 없음
{
visited[next[i]] = visited[now] + 1;
route[next[i]] = now;
bfsq.push(next[i]);
}
}
}
}
void printRoute()
{
cout << visited[K] << endl;
int nowRoute = K;
vector<int> realRoute;
realRoute.push_back(K);
for (int i = 0; i < visited[K]; ++i)
{
realRoute.push_back(route[nowRoute]);
nowRoute = route[nowRoute];
}
for (int i = realRoute.size() - 1; i >= 0; --i)
{
cout << realRoute[i] << " ";
}
}
int main()
{
cin >> N >> K;
visited.assign(SIZE, -1);
route.assign(SIZE, -1);
bfs(N);
printRoute();
}
[BFS] 백준 13549 - 숨바꼭질3 (0) | 2022.04.25 |
---|---|
[DFS, BFS] 백준 2146 - 다리 만들기 (0) | 2022.04.23 |
[DFS, BFS] 백준 16947 - 서울 지하철 2호선 (0) | 2022.04.21 |
[DFS] 백준 16929 - Two Dots (0) | 2022.04.21 |
[BFS] 백준 7576 - 토마토 (0) | 2022.04.15 |