문제
출처 : https://www.acmicpc.net/problem/2251
2251번: 물통
각각 부피가 A, B, C(1≤A, B, C≤200) 리터인 세 개의 물통이 있다. 처음에는 앞의 두 물통은 비어 있고, 세 번째 물통은 가득(C 리터) 차 있다. 이제 어떤 물통에 들어있는 물을 다른 물통으로 쏟아 부
www.acmicpc.net
각각 부피가 A, B, C인 물통이 있고 A, B는 비어있으며 C는 꽉 차있다.
물을 이동 시킬때는 항상 하나의 물통이 꽉차거나 빌때까지만 옮길 수 있다.
이때, 물통 A가 비어있을때, 물통 C에 있을수 있는 물의 양을 모두 구하는 문제다.
풀이
DFS로 풀어도 풀리는 문제다.
A, B, C의 최대 용량이 각각 200이므로, 3차원 체크 배열로 이미 방문한 상태를 재 방문 하지 않도록 만들어주면, 최악의 경우 200*200*200번 반복으로 풀 수 있다.
따라서, 시간복잡도는 O(N^3)이 나온다.
알고리즘은 다음과 같다.
1. 현재 물의 상태 check[A][B][C] 를 이전에 방문했는지 확인한다.
-> 방문했다면, 이 경로는 이미 이전에 모두 방문했음을 알 수 있으므로(나는 DFS로 코드를 작성했음), 더 이상 들어가지 않고 return 한다.
2. 물통 A의 값이 0 이라면 물통 C의 값을 저장한다.
3. 물을 움직인다.
위 과정을 더 이상 방문할 경우가 없을때까지 반복하면 풀리는 문제이다.
이때, 물을 움직이는 경우의 수 는 총 6가지로 다음과 같다.
1. 물을 A -> B로 이동시키는 경우
2. 물을 A -> C로 이동시키는 경우
3. 물을 B -> A로 이동시키는 경우
4. 물을 B -> C로 이동시키는 경우
5. 물을 C -> A로 이동시키는 경우
6. 물을 C -> B로 이동시키는 경우
물을 A1 -> A2로 이동할때는 다음과 같은 식을 세울 수 있다.
- 물을 받은 후 A2의 물의 양 = A2가 이미 갖고있던 물의 양 + min(A2가 받을수 있는 물의 양, A1이 줄 수 있는 물의 양)
- 물을 준 후 A1의 물의 양 = max(0, A1이 갖고있던 물의 양 - A2가 받을 수 있는 물의 양)
위 식을 이용해서 재귀 코드를 작성하면 아래와 같이 나온다.
void solve(int a, int b, int c){
if(check[a][b][c]) return;
check[a][b][c] = true;
if(a == 0 && !visited[c]){
vec.push_back(c);
visited[c] = true;
}
int capA = A - a;
int capB = B - b;
int capC = C - c;
solve(max(0, a - capC), b, c + min(a, capC)); // a to c
solve(max(0, a - capB), b + min(a, capB), c); // a to b
solve(a, max(0, b - capC), c + min(b, capC)); // b to c
solve(a + min(b, capA), max(0, b - capA), c); // b to a
solve(a + min(c, capA), b, max(0, c - capA)); // c to a
solve(a, b + min(c, capB), max(0, c - capB)); // c to b
}
전체 소스코드
https://github.com/devxb/JJUNalgo/blob/master/2251%20물통/main.cpp
GitHub - devxb/JJUNalgo: 백준 알고리즘 소스코드🙃
백준 알고리즘 소스코드🙃. Contribute to devxb/JJUNalgo development by creating an account on GitHub.
github.com
'알고리즘 (2020 : 08 : 10 ~ ) > BFS,DFS' 카테고리의 다른 글
[백준 / BOJ] 2310 어드벤처 게임 (Rust) (1) | 2023.04.30 |
---|---|
[백준 / BOJ] 18809 Gaaaaaaaaaarden (Java) (0) | 2022.06.03 |
[백준 / BOJ] 14442 벽 부수고 이동하기 2 (Java) (0) | 2022.05.15 |
[백준 / BOJ] 1765 닭싸움 팀 정하기 (Java) (0) | 2021.08.30 |
[백준 / BOJ] 5827 What's Up With Gravity (0) | 2021.05.14 |