Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Archives
Today
Total
관리 메뉴

LoCeL

[BOJ 14867/KOI 2017] 물통 본문

PS

[BOJ 14867/KOI 2017] 물통

LoCeL 2020. 8. 4. 16:10

문제는 여기에서 확인가능하다.


A에 담겨있는 물의 양이 $x$, B에 담겨있는 물의 양이 $y$ 일 때, $(x, y)$라고 표현하자.

그럼 $(a, b)$에서 $(c, d)$로 도달하기 위한 작업의 최소 횟수를 BFS로 구할 수 있다.

naive하게 생각하면, 탐색공간의 크기가 $100,000^2$으로 매우 크다. 하지만 관찰을 통해서 $x$와 $y$중 하나는 항상 $0$ 또는 물통에 담을 수 있는 물의 최대값이라는 것을 알 수 있으므로, 탐색공간의 크기를 $400,000$으로 줄일 수 있다.

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
#include<bits/stdc++.h>
 
using namespace std;
 
typedef pair<intint> pii;
typedef pair<pii, int> ppi;
 
map<pii, int> m;
int a, b, c, d;
 
ppi p(int i, int j, int k) {
    return ppi(pii(i, j), k);
}
 
void solve() {
    queue<ppi> q;
    q.push(p(000));
    while(q.size() != 0) {
        ppi t = q.front();
        q.pop();
        int i = t.first.first, j = t.first.second, k = t.second;
        m.insert(p(i, j, k));
        if(m.insert(p(0, j, k+1)).second) q.push(p(0, j, k+1));
        if(m.insert(p(i, 0, k+1)).second) q.push(p(i, 0, k+1));
        if(m.insert(p(a, j, k+1)).second) q.push(p(a, j, k+1));
        if(m.insert(p(i, b, k+1)).second) q.push(p(i, b, k+1));
        int u = min(b-j, i);
        if(m.insert(p(i-u, j+u, k+1)).second) q.push(p(i-u, j+u, k+1));
        u = min(a-i, j);
        if(m.insert(p(i+u, j-u, k+1)).second) q.push(p(i+u, j-u, k+1));
    }
}
 
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cin >> a >> b >> c >> d;
    solve();
    int r = m.find(pii(c, d))->second;
    if(!&& !d) cout << 0;
    else cout << (r > 0 ? r : -1);
    return 0;
}
cs

'PS' 카테고리의 다른 글

[BOJ 8986] 전봇대  (0) 2020.08.04
[BOJ 17842] 버스노선  (0) 2020.08.04
[BOJ 17594] Stop Counting!  (0) 2020.08.04
[UCPC 2019] 이사 풀이  (0) 2019.08.01
[KOI'18] XCorr  (0) 2018.11.09
Comments