https://www.acmicpc.net/problem/13913
[필자 사고]
bfs 탐색을 활용하여 현재위치에서 상대방의 위치까지의 경로를 찾아야 되는 문제이다.
현재위치에서 상대방까지 가는 방식은 숨바꼭질 1,2,3 에서 쉽게 알 수 있따.
다만 경로를 저장하는건 다른 방식앋.
무식하게 매번 배열을 만들어서 경로를 저장하고 큐에 저장하게 되면 메모리와 시간초과가 나게 된다.
새로 배운 방식은 vistied배열에 값에 자신의 이전 노드를 저장하는 방식이다.
vistied[next] = nowIdx; 방식으로 저장하게 되면 어떤 경로로 진행했는지 알 수 있게 된다.
다음은 아래의 코드 해설이다.
1. 입력 처리 및 초기화
먼저, 사용자로부터 출발점 N과 목표점 K를 입력받습니다. 그 후, 방문 여부를 저장하는 배열을 초기화합니다. 이 배열은 BFS 탐색 중에 방문한 노드를 기록하고, 해당 노드에 도달했을 때의 이전 노드를 저장하는 방식으로 경로를 추적합니다.
2. BFS 알고리즘
BFS는 출발점에서부터 목표점까지의 최단 경로를 찾는 데 적합한 알고리즘입니다. 여기서는 우선순위 큐를 사용해 BFS를 수행합니다. 큐에는 현재 위치와 그 위치까지 도달하는 데 걸린 시간을 저장합니다.
탐색 과정은 다음과 같습니다:
- 출발점 N을 큐에 넣고 탐색을 시작합니다.
- 현재 노드에서 이동할 수 있는 3가지 경우(한 칸 앞으로, 한 칸 뒤로, 두 배로 이동)를 고려하여, 각각의 경우에 대해 유효한 범위 내에 있고 아직 방문하지 않은 노드라면 큐에 추가합니다.
- 각 노드가 방문될 때마다, 그 노드에 도달한 이전 노드를 기록하여 경로를 추적할 수 있도록 합니다.
3. 목표 지점 도달 시 경로 추적
BFS 탐색 중 목표점 K에 도달하면, 그때까지의 소요 시간을 출력합니다. 이후, visited 배열을 사용하여 목표점에서 출발점으로 거슬러 올라가면서 경로를 추적합니다. 이 과정에서 각 노드가 어디서 왔는지를 역으로 찾아 경로를 복원한 후, 그 경로를 순서대로 출력합니다.
4. 결과 출력
최종적으로, 목표점에 도달할 수 있는 가장 짧은 시간과 그 경로를 출력합니다. 경로는 목표점에서 출발점까지의 노드를 차례대로 출력하며, 경로 추적이 완료되면 탐색이 종료됩니다.
[소스 코드]
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef pair<int, int> Node;
struct cmp {
bool operator()(Node a, Node b) {
return a.second > b.second;
}
};
int N, K;
const int MAX_SIZE = 100000;
vector<int> visited;
priority_queue<Node, vector<Node>, cmp> pq;
int resultNowCount = -1;
void Input() {
cin >> N >> K;
visited.resize(MAX_SIZE + 1, -1);
}
bool isInside(int num) {
if (num >= 0 && num <= MAX_SIZE)return true;
return false;
}
void BFS(int startIdx) {
pq.push({ startIdx,0 });
visited[startIdx] = startIdx;
while (!pq.empty()) {
int nowIdx = pq.top().first;
int nowCount = pq.top().second;
pq.pop();
if (nowIdx == K) {
cout << nowCount << '\n';
vector<int> path;
for (int i = K; i != N; i = visited[i]) {
path.push_back(i);
}
path.push_back(N);
for (int i = path.size() - 1; i >= 0; i--) {
cout << path[i] << " ";
}
cout << '\n';
return;
}
int plus = nowIdx + 1;
int minus = nowIdx - 1;
int multi = nowIdx * 2;
if (isInside(plus) && visited[plus] == -1) {
pq.push({ plus,nowCount + 1 });
visited[plus] = nowIdx;
}
if (isInside(minus) && visited[minus] == -1) {
pq.push({ minus,nowCount + 1 });
visited[minus] = nowIdx;
}
if (isInside(multi) && visited[multi] == -1) {
pq.push({ multi,nowCount + 1 });
visited[multi] = nowIdx;
}
}
}
void GameStart() {
BFS(N);
}
int main(void) {
Input();
GameStart();
}
'백준 > 그래프' 카테고리의 다른 글
백준 2668 c++ "숫자고르기" -PlusUltraCode- (2) | 2024.09.30 |
---|---|
백준 1520 c++ "내리막 길" -PlusUltraCode- (1) | 2024.09.27 |
백준 12851 c++ "숨박꼭질2" -PlusUltraCode- (0) | 2024.09.26 |
백준 1414 c++ "블우이웃돕기" -PlusUltraCode- (1) | 2024.09.20 |
백준 1389 c++ "케빈 베이컨의 6단계 법칙" -PlusUltraCode- (0) | 2024.09.06 |