말랑말랑한 개발자 이야기

[백준 1697번] 숨바꼭질 본문

알고리즘/백준

[백준 1697번] 숨바꼭질

말랑너구리 2021. 1. 27. 01:33

[백준 1697번] 숨바꼭질

www.acmicpc.net/problem/1697

 

1697번: 숨바꼭질

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 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는 정수이다.

 

 

 출력

 수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.

 

 

 풀이

#include <iostream>
#include <queue>
using namespace std;
int N, K;
bool visit[100001];
int ff(){
	queue<pair<int, int>> qu;
	qu.push(make_pair(N, 0));
	
	while(!qu.empty()){
		pair<int, int> a = qu.front();
		qu.pop();
		
		if(a.first == K) return a.second;
		else{
			if(a.first + 1 <= 100000 && !visit[a.first + 1]){
				qu.push(make_pair(a.first + 1, a.second + 1));
				visit[a.first + 1] = true;
			}
			if(a.first - 1 >= 0 && !visit[a.first - 1]){
				qu.push(make_pair(a.first - 1, a.second + 1));
				visit[a.first - 1] = true;
			}
			if(a.first * 2 <= 100000 && !visit[a.first * 2]){
				qu.push(make_pair(a.first * 2, a.second + 1));
				visit[a.first * 2] = true;
			}
		}
	}
}

int main() {
	cin >> N >> K;
	cout << ff();
	return 0;
}
#include <iostream>
#include <queue>
using namespace std;
int N, K;
int visit[100001];
int ff(){
	queue<int> qu;
	qu.push(N);
	visit[N] = 0;
	
	while(!qu.empty()){
		int a = qu.front();
		qu.pop();
		
		if(a == K) return visit[a];
		else{
			if(a + 1<= 100000 && visit[a + 1] == 0){
				qu.push(a + 1);
				visit[a + 1] = visit[a] + 1;
			}
			if(a - 1 >= 0 && visit[a - 1] == 0){
				qu.push(a - 1);
				visit[a - 1] = visit[a] + 1;
			}
			if(a * 2 <= 100000 && visit[a * 2] == 0){
				qu.push(a * 2);
				visit[a * 2] = visit[a] + 1;
			}
		}
	}
}

int main() {
	cin >> N >> K;
	cout << ff();
	return 0;
}

 비슷하지만 연습겸 조금 다른 방법으로 구현해보았다. 하나는 큐에 pair를 담으면서 몇초 후 인지 같이 묶고, visit 체크는 bool 배열로 하는 방법이고 다른 하나는 visit 체크와 몇초 후 인지를 동시에 하는 방법이다. 말로 설명이 이상한데 코드를 보면 쉽게 알 수 있다. 처음에는 3의 거듭제곱 형식으로 시간초과가 나지 않을까 생각했었는데 아니었나보다.

 이 문제도 10달전, 4달전 푸려고 했던 흔적을 보니 성장했음을 느낄 수 있었다. 처음에는 아예 풀지도 못했고 4달전에는 풀긴했는데 몇초 후 인지 처리를 못해서 큐를 두개 만들어서 여기 넣었다 저기 넣었다 하는 방식으로 풀은걸 보니 새록새록하다.

 

'알고리즘 > 백준' 카테고리의 다른 글

[백준 2635번] 수 이어가기  (1) 2021.01.28
[백준 2178번] 미로 탐색  (0) 2021.01.27
[백준 2667번] 단지번호붙이기  (0) 2021.01.27
[백준 1503번] 세 수 고르기  (0) 2021.01.27
[백준 2661번] 좋은수열  (0) 2021.01.26