https://www.acmicpc.net/problem/13549
13549번: 숨바꼭질 3
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 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로 이동하게 된다. 순간이동을 하는 경우에는 0초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
출력
수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
두 점 사이의 거리를 구하는 문제이므로 다익스트라 알고리즘을 생각해낼 수 있다.
#include <iostream>
#include <queue>
using namespace std;
#define MAX 100001
typedef pair<int, int> point;
bool vis[100001];
int N, K;
void solve()
{
priority_queue<point, vector<point>, greater<point> > pq;
pq.push(make_pair(0, N));
vis[N] = true;
while (!pq.empty())
{
point top = pq.top();
pq.pop();
int cost = top.first;
int cur = top.second;
if (cur == K)
{
cout << cost;
break;
}
if (cur < 2 * K)
{
if (cur * 2 < MAX && !vis[cur * 2])
{
vis[cur * 2] = true;
pq.push(make_pair(cost, cur * 2));
}
if (cur - 1 >= 0 && !vis[cur - 1])
{
vis[cur - 1] = true;
pq.push(make_pair(cost + 1, cur - 1));
}
if (cur + 1 < MAX && !vis[cur + 1])
{
vis[cur + 1] = true;
pq.push(make_pair(cost + 1, cur + 1));
}
}
}
}
int main()
{
cin >> N >> K;
if (N >= K)
cout << N - K;
else
solve();
}
처음 제출하였을때는 아래의 코드로 정답을 받았다.
#include <iostream>
#include <queue>
using namespace std;
#define INF 987654321;
typedef pair<int, int> point;
int dist[400010];
int N, K;
void solve()
{
int res = INF;
priority_queue<point, vector<point>, greater<point> > pq;
pq.push(make_pair(0, N));
dist[N] = 0;
while (!pq.empty())
{
point top = pq.top();
pq.pop();
int cost = top.first;
int cur = top.second;
if (cur == K)
{
res = cost;
break;
}
if (cur < 2 * K)
{
if(dist[cur - 1] > cost + 1){
dist[cur - 1] = cost + 1;
pq.push(make_pair(cost + 1, cur - 1));
}
if(dist[cur + 1] > cost + 1){
dist[cur + 1] = cost + 1;
pq.push(make_pair(cost + 1, cur + 1));
}
if(dist[cur * 2] > cost){
dist[cur * 2] = cost;
pq.push(make_pair(cost, cur * 2));
}
}
}
cout << res;
}
int main()
{
cin >> N >> K;
for(int i = 0 ; i <= 2* K;i++)
dist[i] = INF;
if(N >= K)
cout << N - K;
else
solve();
}
하지만 먼저 처리된 dist가 무조건 작을 것 같아 int 배열이 아닌 bool 배열로 전환할 수 있어서 바꾸려 하였다. 바꾸었더니 정답 처리가 되지 않아 생각을 해본 결과 -1 +1 *2의 순서로 조건문을 작성한 경우 1의 경우 +1과 *2의 경우 모두 2가 되지만 cost는 +1의 경우가 더 높게 된다. int 배열의 경우 cost 가 *2 가 더 낮아 최신화가 되지만 bool 배열의 경우 +1의 경우에서 vis 가 true가 되어 *2에서 처리되지 못하여 틀리게 되었던 것이다. cost 가 낮은 *2를 먼저 계산해야 최신화할 수 있다.
'코딩 > 백준' 카테고리의 다른 글
[백준]1261번 알고스팟 - C++ (0) | 2022.11.03 |
---|---|
[백준]1504번 특정최단경로 - C++ (0) | 2022.11.02 |
[백준] 1967번 트리의 지름 - C++ (2) | 2022.10.05 |
[백준] 1753번 최단경로 - C++ (0) | 2022.10.04 |
[백준]7576번 토마토 - C/C++ (0) | 2022.10.02 |