백준 1697 - 숨바꼭질
1 minute read
문제링크
오답을 이끌었던 문제 접근
- 수빈이의 현재 위치를 X, 동생의 위치를 K라고 했을 때, 동생이 수빈이보다 왼쪽에 위치하는 경우 X=X-1, 동생이 수빈이보다 오른쪽에 위치하는 경우 X=X+1 또는 X=2*X 로 이동할 수 있을 것이라 생각했다.
- 따라서 BFS를 구현할 때도 방문표시배열이 필요가 없었으며 수빈이의 위치와 동생의 위치가 같아지는 경우를 탈출 조건으로 선택하였다.
- 방문한 노드에는 현재 위치 정보와 시간을 담을 수 있도록 구조체를 활용하였다.
잘못된 접근이었던 이유
- 동생이 수빈이보다 왼쪽에 있건, 오른쪽에 있건 수빈이가 움직일 수 있는 방향에 대한 제약은 없다. (올바른 문제 접근 시 수빈이가 방문한 좌표로 다시 방문하지 않도록 제한을 두는 것과는 별개로)
- 수빈이가 현재 위치(X)에서 -1만큼 이동한 후 순간이동(x2)을 하는 경우도 고려할 수 있어야 한다.
문제 접근 방향 (Solution)
- 수빈이가 이동할 수 있는 모든 경우의 수에 대해서 너비우선탐색을 진행한다.
- 수빈이가 방문한 좌표는 다시 방문하지 않는다.
- 좌표 정보, 시간 정보를 함께 담을 수 있도록 구조체를 선언한다.
구현 결과
#include <iostream>
#include <queue>
#include <memory.h>
using namespace std;
typedef struct _ele
{
int pos;
int time;
} Ele;
bool visited[100001]; // 방문표시
bool check_valid(int pos)
{
if (0 <= pos && pos <= 100000 && visited[pos]==false)
return true;
else
return false;
}
int bfs(int x, int k)
{
memset(visited, false, sizeof(visited));
Ele el = { x, 0 }; // 처음 위치와 시간 정보
int next_pos1, next_pos2, next_pos3, time;
queue<Ele> q;
q.push(el);
while (!q.empty())
{
el = q.front();
time = el.time;
visited[el.pos] = true;
q.pop();
if (el.pos == k)
return el.time;
next_pos1 = el.pos - 1;
next_pos2 = el.pos + 1;
next_pos3 = el.pos * 2;
if (check_valid(next_pos1))
{
el.pos = next_pos1;
el.time = time + 1;
q.push(el);
}
if (check_valid(next_pos2))
{
el.pos = next_pos2;
el.time = time + 1;
q.push(el);
}
if (check_valid(next_pos3))
{
el.pos = next_pos3;
el.time = time + 1;
q.push(el);
}
}
}
int main()
{
int n, k; // 수빈이의 처음 위치(n), 동생의 위치(k)
cin >> n >> k;
int ans = bfs(n, k);
cout << ans << endl;
return 0;
}
Leave a comment