ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 13549(숨바꼭질3)
    전공/알고리즘 2020. 6. 29. 15:11

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

     

    13549번: 숨바꼭질 3

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

    www.acmicpc.net

     

    어떻게 하면 원하는 값까지 도달할 수 있을까. dfs는 한곳을 엄청 깊게 판다. 

     

    그래서 원하는 값까지 도달하더라도 그 값이 최솟값이 아닐 가능성이 농후하다. 그래서 bfs

     

    bfs에 단순 queue로 구성을 하려니 순간이동할때는 시간 소모가 안된다고 한다. 그래서 만약 단순 queue로 구성을 한다고 하면 경로는 더 길지만 시간이 적게 걸리는 경우를 확인하지 못한다. 

     

    따라서 priority_queue로 시간이 작은 것부터 조사를 하면 괜찮지 않을까 생각한다. 

     

    근데 여기서 만약에 조건을 추가하지 않고 단순하게 두배, +1, -1로 하게된다면 순간이동하는 경우에는 시간이 소모되지 않으므로 계속해서 순간이동하는 것부터 조사하게 될것이다. 

     

    그렇다면 조건을 넣어주자 찾으려는 값이 40이고 현재의 값이 80이라면 현재의 값에 두배를 했을때 최단경로가 될 수 있을까? 찾으려는 값을 초과해서 두배를 한다면 최소 N번을 -해야하므로

     

    걸리는 시간 >= 시간 + N 이 된다.

     

    따라서 조건을 잘 넣어서 쓸데없는 연산을 하지 않도록 해준다. 

     

    여기서 나는

    			if (p.second * 2 < MAX - 1 && p.second  < K * 4)
    

     

    이렇게 넣었다. 

     

    그리고 주의해야 할 점이 하나 더 있다. 

     

    만약에 100,000까지 가고싶다고 하자 

    50,001에서 간다고하면 100,002까지 간 후에 -2하는것이 최단 경로일 것이다.

     

    하지만 만약에 배열의 크기를 100,001까지로 제한해둔다면? 

     

    원하는 결과를 찾을 수 없다. 따라서 배열의 크기를 잘 설정해야 한다. 

     

    100,000 - N vs N*2 - 100,000 를 비교해서 대충 같아지는 N값의 두배이상을 설정해주면 되겠다.

    #include<iostream>
    #include<queue>
    #include<utility>
    using namespace std;
    #define MAX 200002
    
    priority_queue<pair<int, int> > pq;
    pair<int, int> p;
    int N, K, num;
    bool visited[MAX];
    
    void solve() {
    	pq.push(make_pair(0, N));
    	while (!pq.empty()) {
    		p = pq.top();
    		pq.pop();
    		if (p.second == K) {
    			cout << -p.first << "\n";
    			return;
    		}
    		if (!visited[p.second]) {
    			visited[p.second] = true;
    			if(p.second < MAX-1)
    				pq.push(make_pair((p.first - 1), p.second + 1));
    			if (p.second > 0)
    				pq.push(make_pair((p.first - 1), p.second - 1));
    			if (p.second * 2 < MAX - 1 && p.second  < K * 4)
    				pq.push(make_pair(p.first, p.second * 2));
    		}
    
    	}
    
    }
    
    
    int main() {
    	ios_base::sync_with_stdio(false);
    	cin.tie(0);
    	cin >> N >> K;
    	solve();
    }

     

     

    다른 사람들 코드를 확인해보니깐, 그냥 queue로도 풀었다. 한번 코드 참조해서 공부 해봐야겠다.

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

    백준 1967(트리의 지름)  (0) 2020.06.30
    백준 17396(백도어)  (0) 2020.06.30
    백준 1916(최소비용 구하기)  (0) 2020.06.29
    백준 1753(최단경로)  (0) 2020.06.29
    백준 2665(미로만들기)  (0) 2020.06.28

    댓글

Designed by Tistory.