Skip to content

Commit

Permalink
2024-03-11 숨바꼭질 4
Browse files Browse the repository at this point in the history
  • Loading branch information
InSange committed Mar 11, 2024
1 parent faecaf6 commit 2afe394
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 1 deletion.
118 changes: 118 additions & 0 deletions InSange/BFS/13913.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include <iostream>
#include <queue>
#include <stack>
#include <cstring>

using namespace std;

const int MAX_INT = 9999999;

int N, K;
pair<int, int> visited[100001];
queue<int> q; // 현재 이동해야할 칸들을 BFS로 방문하기 위해서 큐를 선언
stack<int> st; // 도착지(K)에서 백트래킹을 통해 출발지(N)까지 방문했던 점들을 넣어 순서대로 출력하기 위해 스택을 선언

bool Check(int index)
{ // 이동할 수 있는 점 범위( 0 <= x <= 100,000 )를 벗어나면 안된다!
if (index < 0 || index > 100000) return false;
return true;
}

void Init()
{ // 수빈이(N : 출발지)와 동생(K : 목적지) 값 설정
cin >> N >> K;
// 0 번째 인덱스도 범위에 속하기 때문에 MAX_INT로 초기화 해준다.
// 첫번째 값은 해당 번호를 방문하기 이전의 번호를 저장하고, 두번째 값은 해당 번호로 오기까지의 횟수를 저장한다.
for (int i = 0; i < 100001; i++)
{
visited[i] = { MAX_INT, MAX_INT };
}
// 출발 지점은 0번 횟수로 채워넣기
visited[N] = { N, 0 };
}

void Solve()
{ // 3가지의 경우의 수
if (N == K) // 1. 수빈(N)과 동생(K)가 같은 위치에 있을 경우 이동하는 칸은 0이고 해당 위치를 바로 출력해준다.
{
cout << visited[N].second << "\n" << N;
return;
}
else if (N > K) // 2. 수빈(N)이 동생(K)보다 큰 경우 K로 감소하는 접근은 -1 밖에 없기 때문에 -1로만 계산한 값들을 출력해준다.
{
cout << N-K << "\n";
while (N != K)
{
cout << N << " ";
N--;
}
cout << N << "\n";
return;
}
else// if(N < K) // 3. 수빈(N)이 동생(K)보다 작은 경우 +1, *2 뿐만 아니라 -1 * 2로 빠른 접근을 노려 볼수도 있다. ex) 5에서 8로 갈 경우 (1) 5 -> 4 -> 8 (2) 5 -> 10 -> 9 -> 4
{
// 수빈이(N: 출발지) 값을 넣어준다.
q.push(N);

while (!q.empty())
{ // 현재 수빈이의 위치를 큐에서 꺼내준다.
int cur_num = q.front();
q.pop();
// 현재 이동한 칸의 수와 다음 이동할 점에 대한 위치 값을 저장할 변수들을 선언해준다.
int cur_cnt, next_num;
cur_cnt = visited[cur_num].second;
// 현재 위치에서 -1만큼 이동했을 경우.
next_num = cur_num - 1;
if (Check(next_num) && visited[next_num].second > cur_cnt + 1)
{
q.push(next_num);
visited[next_num].first = cur_num;
visited[next_num].second = cur_cnt + 1;
}
if (next_num == K) break;
// 현재 위치에서 +1만큼 이동했을 경우.
next_num = cur_num + 1;
if (Check(next_num) && visited[next_num].second > cur_cnt + 1)
{
q.push(next_num);
visited[next_num].first = cur_num;
visited[next_num].second = cur_cnt + 1;
}
if (next_num == K) break;
// 현재 위치에서 *2만큼 이동했을 경우.
next_num = 2 * cur_num;
if (Check(next_num) && visited[next_num].second > cur_cnt + 1)
{
q.push(next_num);
visited[next_num].first = cur_num;
visited[next_num].second = cur_cnt + 1;
}
if (next_num == K) break;
}
// 출발지에서 도착지까지 가는데 걸린 칸의 수
cout << visited[K].second << "\n";
// 도착지에서 출발지까지 방문했던 점들을 저장하여 출력 저장할때는 K->N이지만 출력할때는 N->K로 출력이 됨!
do {
st.push(K);
K = visited[K].first;
} while (K != N);
st.push(N);

while (!st.empty())
{
cout << st.top() << " ";
st.pop();
}
}
}

int main()
{
cin.tie(nullptr);
ios::sync_with_stdio(false);

Init();
Solve();

return 0;
}
3 changes: 2 additions & 1 deletion InSange/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

| 차시 | 날짜 | 문제유형 | 링크 | 풀이 |
|:----:|:---------:|:----:|:-----:|:----:|
| 1차시 | 2023.10.27 | BFS | - | - |
| 1차시 | 2024.03.11 | BFS | [숨바꼭질 4](https://www.acmicpc.net/problem/13913) | - |
=======
---

0 comments on commit 2afe394

Please sign in to comment.