https://www.acmicpc.net/problem/2251
2251번: 물통
각각 부피가 A, B, C(1≤A, B, C≤200) 리터인 세 개의 물통이 있다. 처음에는 앞의 두 물통은 비어 있고, 세 번째 물통은 가득(C 리터) 차 있다. 이제 어떤 물통에 들어있는 물을 다른 물통으로 쏟아 부
www.acmicpc.net
2251 : 물통 / 문제 소개
부피가 A B C (1<= A,B,C <= 200 ) 리터인 세개의 물통이 있다.
처음에는 C 물통에만 가득 차 있다.
이제 다른 물통들로 쏟아 부울 수 있는데 조건이 있다.
한 물통이 비거나 or 다른 한 물통이 가득 찰 때 까지 물을 쏟아 부울 수 있다.
A물통이 비어있을 때 C물통에 담길 수 있는 물의 양을 모두 구해내시오!!
풀이 과정
물통은 전부 3개다.
한개의 물통에 대해서 서로 다른 두개의 물통에 동시에 부울 수 없다. 물을 붓는 물통이 비거나, 부어짐을 당하는 물통이 가득 찰 때 까지 물을 붓기 때문이다.
그렇다면 각각의 물통에 대해서 다른 물통으로 부울 수 있는 경우의 수는
A 물통에서 B물통으로
A 물통에서 C물통으로
B 물통에서 A물통으로
B 물통에서 C물통으로
C 물통에서 A물통으로
C 물통에서 B물통으로
6가지 서로 다른 경우의 수를 통해 각각의 물통에서 물을 부울 수 있다.
예를들어
input
8 9 10
일때 물통의 크기는 maxA = 8 , maxB = 9, maxC = 10으로 정할 수 있다.
초기 물통에 들어있는 물 양은
A B C
0 0 10이다.
이 경우에서 물을 붓는 경우는
0 9 1
8 0 2 두개가 나온다.
첫번째 (0 9 1)의 경우 초기값 0 0 10일 때 C에서 B로 물을 붓는 방법은
B = maxB , C = ( b + c ) - maxC로 구할 수 있다.
그렇다면
A B C
8 0 2의 경우에서 C에서 B로 물을 붓는 방법은 위에서 구한 식을 이용해
B = maxB, C = ( b + c ) - maxC 로 계산이 될 까?
그렇지 않다.
이 경우는 C에서 B로 물을 부울 수 있는데 C의 양이 B의 양보다 크지 않음으로 B는 가득 찰 수 없다.
B = b + c, C = 0 이렇게 계산해주어야 한다.
C에서 B로 물을 부을 때 C와 B에 들어있는 물통의 양에 따라서 C, B의 부피가 계산된다는 것이다.
이렇게 경우를 따지면 6 * 2 == 12개의 경우의 수가 나온다.
이렇게 특정 조건에 따라 물의 높이가 다른 3개의 물통이 존재하는데 반복해서 구해질 수 있음으로
visited를 통해 방문 체크를 한다.
또한 새로 구한 물통의 물 높이에서 다른 물통으로 물을 부울 수 있기에 queue에 추가를 해가면서 구하면 된다.
그리고 A == 0일 때 C의 물 높이를 정답 배열에 저장해나가서 소팅 후 답을 출력하면 된다!
코드 구현
import Foundation
func BFS(_ ABC : [Int])
{
let maxA = ABC[0] , maxB = ABC[1] , maxC = ABC[2]
var queue = [(0,0,maxC)]
var index = 0
var res = ""
var ans = [Int]()
var visited = Array(repeating: Array(repeating: Array(repeating: false,count:ABC[2] + 1), count :ABC[1] + 1) , count: ABC[0] + 1)
visited[0][0][maxC] = true
while queue.count != index
{
let (curA,curB,curC) = queue[index]
index += 1
if curA == 0
{
ans.append(curC)
}
// C에서 B에 물을 채우는 경우 . a 는 상관x
if (curB + curC) > maxB && !visited[curA][maxB][(curB+curC)-maxB]
{
visited[curA][maxB][(curB+curC)-maxB] = true
queue.append((curA,maxB,(curB+curC)-maxB))
}
else if curB + curC <= maxB
{
if !visited[curA][curB+curC][0]
{
visited[curA][curB+curC][0] = true
queue.append((curA,curB+curC,0))
}
}
// C에서 A에 물을 채우는 경우. B는 상관 x
if (curA + curC) > maxA && !visited[maxA][curB][(curA+curC) - maxA]
{
visited[maxA][curB][(curA+curC)-maxA] = true
queue.append((maxA,curB,(curA+curC)-maxA))
}
else if curA+curC <= maxA
{
if !visited[curA+curC][curB][0]
{
visited[curA+curC][curB][0] = true
queue.append((curA+curC,curB,0))
}
}
// B에서 A에 물을 채우는 경우. C는 상관 x
if (curB + curA) > maxA && !visited[maxA][(curB + curA) - maxA][curC]
{
visited[maxA][(curB+curA)-maxA][curC] = true
queue.append((maxA,(curB+curA)-maxA,curC))
}
else if curB+curA <= maxA
{
if !visited[curA+curB][0][curC]{
visited[curA+curB][0][curC] = true
queue.append((curA+curB,0,curC))
}
}
//B에서 C에 물을 채우는 경우. A는 상관x
if (curB + curC) > maxC && !visited[curA][(curB+curC)-maxC][maxC]
{
visited[curA][(curB+curC)-maxC][maxC] = true
queue.append((curA,(curB+curC)-maxC,maxC))
}
else if curB+curB <= maxC
{
if !visited[curA][0][curB+curC]
{
visited[curA][0][curB+curC] = true
queue.append((curA,0,curB+curC))
}
}
// A에서 B에 물을 채우는 경우. C는 상관x
if (curA + curB) > maxB && !visited[(curA+curB)-maxB][maxB][curC]
{
visited[(curA+curB)-maxB][maxB][curC] = true
queue.append(((curA+curB)-maxB,maxB,curC))
}else if curA + curB <= maxB
{
if !visited[0][curA+curB][curC]
{
visited[0][curA+curB][curC] = true
queue.append((0,curA+curB,curC))
}
}
// A에서 C에 물을 채우는 경우. B는 상관x
if (curA + curC) > maxC && !visited[(curA+curC)-maxC][curB][maxC]
{
visited[(curA+curC)-maxC][curB][maxC] = true
queue.append(((curA+curC)-maxC,curB,maxC))
}
else if curA+curC <= maxC
{
if !visited[0][curB][curA+curC]
{
visited[0][curB][curA+curC] = true
queue.append((0,curB,curA+curC))
}
}
}
ans.sort()
ans.forEach
{
res += "\($0) "
}
print(res)
}
func BOJ_2251()
{
var ABC = readLine()!.split(separator: " ").map{Int(String($0))!}
BFS(ABC)
}
BOJ_2251()
visit my github
'백준 PS일지 > DFS&BFS' 카테고리의 다른 글
[백준/Swift] 1726 : 로봇 (0) | 2022.07.18 |
---|---|
[백준/Swift] 14503 : 로봇 청소기 문제 뿌수기!! (0) | 2022.07.18 |
[백준/Swift] 14442 : 벽 부수고 이동하기 2 (0) | 2022.07.16 |
[백준/Swift] 3184 : 양 (0) | 2022.07.16 |