ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 1697(숨바꼭질)
    전공/알고리즘 2020. 6. 17. 13:57

    https://www.acmicpc.net/problem/1697

     

    1697번: 숨바꼭질

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

    www.acmicpc.net

     

     

    조건들을 추가해서 더 쉽게 접근할 수 있을까. 고민을 해보았지만, 반례들이 존재했다. 그래서 그냥 bfs로 완전탐색을 하였다. dfs대신 bfs를 선택한 이유는 이 문제는 전형적인 턴제의 문제여서이다. 그리고 만약에 dfs로 접근을 한다면, 멈출 조건을 설정하는 것이 너무 까다롭게 된다. 

     

    그래서 턴제의 bfs를 선택하였다. 

     

    *2 , +1, -1 을 계속해서 한 뒤에 몇 번을 해야지 최소가 나올까 인데, 만약에 bfs로 한다면 모든 경우에 대해서 구한 뒤 그 중 최솟값을 결정하는게 아니라 무조건 최소의 경우가 결괏값으로 한번에 저장이 된다. 

     

    그리고, 배열 index 범위초과 접근에 대해서 주의하자. 범위를 벗어나게 된다면 런타임 에러가 발생한다.  

     

    만약 if(v[index-1] > 0 && index > 0) 이런 조건문이 있다고 한다면, v[index-1] > 0 에 대해서 조사를 한 뒤에 그 다음 조건에 대해서 확인을 하기 때문에, index>0조건을 먼저 넣는 것이 중요하다. 

     

     

    그리고 대부분의 그래프 문제와 같이 visited를 잘 사용하는 것이 중요하다.

    #include<iostream>
    #include<queue>
    using namespace std;
    #define MAX 100002
    
    int N, K, cnt=1, tmp;
    bool visited[MAX] = { false };
    bool answer = false;
    queue<int> q;
    queue<int> q2;
    
    void bfs() {
    	while (1) {
    		while (!q.empty()) {
    			tmp = q.front();
    			q.pop();
    			if (tmp<MAX && !visited[tmp + 1]) {
    				q2.push(tmp + 1);
    				visited[tmp + 1] = true;
    				if ((tmp + 1) == K) answer = true;
    			}
    			if (tmp>0 && !visited[tmp - 1]) {
    				q2.push(tmp - 1);
    				visited[tmp - 1] = true;
    				if ((tmp - 1) == K) answer = true;
    			}
    			if (2*tmp <= MAX && !visited[2 * tmp]) {
    				q2.push(2 * tmp);
    				visited[2 * tmp] = true;
    				if ((2 * tmp) == K) answer = true;
    			}
    			if (answer) {
    				cout << cnt << "\n";
    				return;
    			}
    			if (q.empty()) cnt++;
    		}
    		while (!q2.empty()) {
    			tmp = q2.front();
    			q2.pop();
    			if (tmp < MAX && !visited[tmp + 1]) {
    				q.push(tmp + 1);
    				visited[tmp + 1] = true;
    				if ((tmp + 1) == K) answer = true;
    			}
    			if (tmp > 0 && !visited[tmp - 1]) {
    				q.push(tmp - 1);
    				visited[tmp - 1] = true;
    				if ((tmp - 1) == K) answer = true;
    			}
    			if (2*tmp <= MAX && !visited[2 * tmp]) {
    				q.push(2 * tmp);
    				visited[2 * tmp] = true;
    				if ((2 * tmp) == K) answer = true;
    			}
    			if (answer) {
    				cout << cnt << "\n";
    				return;
    			}
    			if (q2.empty()) cnt++;
    		}
    	}
    }
    
    int main() {
    	cin >> N >> K;
    	if (N == K) {
    		cout << 0 << "\n";
    		return 0;
    	}
    	q.push(N);
    	visited[N] = true;
    	bfs();
    }

    '전공 > 알고리즘' 카테고리의 다른 글

    백준 9019(DSLR)  (0) 2020.06.22
    백준 2636(치즈)  (0) 2020.06.19
    백준 1260(dfs와 bfs)  (0) 2020.06.17
    백준 7576(토마토) bfs  (0) 2020.06.16
    백준 10026(적록색약) dfs  (0) 2020.06.16

    댓글

Designed by Tistory.