LoCeL
[BOJ 14867/KOI 2017] 물통 본문
문제는 여기에서 확인가능하다.
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<int, int> 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(0, 0, 0)); 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(!c && !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