알고리즘/백준 BAEK JOON

1697.숨바꼭질

IMyoungho 2020. 5. 27. 03:21
 

1697번: 숨바꼭질

문제 수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가

www.acmicpc.net

이번에 풀어볼 문제는 백준의 1697 숨바꼭질이다. 어떻게 접근을 시작하는지, 설계를 시작하는지에 따라

체감하는 난이도는 크게 차이가 날 것 같다. 나같은 경우에는 금방 풀이법을 찾아냈다.

대부분이 금방 찾아내는 경우라면 쉬운편에 속하는 것이고 아닌 사람들 굉장히 헤맬 것이다.

결론을 말하자면 이번문제는 BFS로 간단하게 풀어낼 수 있는 문제이다.

주의할 점이 있다면 같은 연산을 줄이는 것이다.

이것만 주의하면 충분히 풀 수 있는 문제이다!! 

# 배열을 선언했다면 연산 범위를 주의해야한다 => 그렇지않으면 런타임 에러 지옥에 빠질 수도 있다.

# 또다른 실수로는 불필요한 연산이 늘어나면 시간초과를 겪을 수 있다.

 


 

< Code 설명 >

#pragma warning(disable:4996)
#include <iostream>
#include <queue>
#define MAX 100001
using namespace std;

int n, k; //n이 수빈, k가 동생

int check[MAX]; // 연산한 적이 있는 값을 체크하는 유무이다. 0으로 초기화

int brute(){
	queue<int>q; // 탐색할 숫자가 저장되는 큐
	q.push(n); // 시작 값이 저장
	check[n] = 1; // 시작값을 1로 초기화 => 0으로 초기화하면
                  // 아래의 로직으로인해 여러번 계산하게 되므로 주의!!
                 
	while (!q.empty()){
		int x = q.front(); // 큐의 값 사용
		q.pop(); // 위에서 저장했으므로 큐에서 제거
		if (check[k]) // 우리가 찾는 값이 true가 되면
			return check[k]; // 그 값을 리턴하고 종료
		if (x - 1 >= 0 && !check[x - 1]){ // "큐의 값 - 1"의 조건
			check[x - 1] = check[x] + 1; // 성립시 이전의 값 + 1을 저장
			q.push(x - 1); // 해당 숫자 큐에 저장
		}
		if (x + 1 < MAX && !check[x + 1]){ // "큐의 값 + 1"의 조건
			check[x + 1] = check[x] + 1;// 성립시 이전의 값 + 1을 저장
			q.push(x + 1); // 해당 숫자 큐에 저장
		}
		if (x * 2 < MAX  && !check[x * 2]){// "큐의 값 * 2"의 조건
			check[x * 2] = check[x] + 1;// 성립시 이전의 값 + 1을 저장
			q.push(x * 2); // 해당 숫자 큐에 저장
		}
	}
}

int main() {
	freopen("1697.txt", "r", stdin);
	cin >> n >> k;
	cout << brute()-1 << "\n"; // 리턴값 출력
	return 0;
}

 

 

< 로직 설명 >

위의 코드를 그림으로 표현하자면  다음과 같다. 그림을 보면 이해가 빠를 것이다. 

이미 진행된 연산을 check 배열로 판단해서 있으면 굳이 값을 저장하여 탐색하지 않는 로직이다.

반응형