문제
https://www.acmicpc.net/problem/1697
1697번: 숨바꼭질
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일
www.acmicpc.net
풀이
X가 3가지 연산을 이용해 K가 되는 최소 연산 횟수를 구하는 문제다.
X에서 x-1, x+1, x*2를 할 수 있으니 3^n의 모든 경우의 수를 싹싹 뒤져서 만드는게 맞는걸까?
아무리 생각해봐도 아닌 것 같아서 검색의 도움을 받았다.
하지만 싹싹 뒤지는게 맞았었다.
수학 공식으로 풀 수 있을거라 생각했는데 내가 검색을 잘 못한건지 못 찾았다.
최단 시간을 구하는거라 BFS를 이용하여 풀었다.
🚩주의할 점
- 큐 사이즈를 for문 조건문에 q.size()로 넣은 점
1 2 3 4 | int qSize = q.size(); for(int i=0; i { // ... | cs |
q.size()는 for문 안에서 증가된다. 해당 sec에서 추가된 queue만 검토한 후 sec++ 해야 하기때문에 int qSize 변수를 선언해주었다.
- 최댓값을 검사하려고 isValid()라는 함수를 생성했는데 <=, >=라는 연산을 써서.. 틀렸다..........
1 2 3 4 5 6 7 | bool isValid(int num) { if(num > MAX || num < 0) return false; return true; } | cs |
소스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #include <iostream> #include <queue> #define MAX 100000 std::queue<int> q; bool visited[MAX + 1]; bool isValid(int num) { if(num > MAX || num < 0) return false; return true; } int BFS(int K) { int sec = 0; int data = 0; while(1) { int qSize = q.size(); for(int i=0; i<qSize; ++i) { data = q.front(); q.pop(); if(data == K) { return sec; } if(isValid(data-1) && !visited[data-1]) { visited[data-1] = true; q.push(data-1); } if(isValid(data+1) && !visited[data+1]) { visited[data+1] = true; q.push(data+1); } if(isValid(data<<1) && !visited[data<<1]) { visited[data<<1] = true; q.push(data<<1); } } sec++; } } int main() { int N=0, K=0; std::cin >> N >> K; visited[N] = true; q.push(N); std::cout << BFS(K); return 0; } | cs |