첫 번째 물통(용량이 A인)이 비어 있을 때, 세 번째 물통(용량이 C인)에 담겨있을 수 있는 물의 양을 모두 구하기
입력 | 출력 |
---|---|
8 9 10 | 1 2 8 9 10 |
: dfs/bfs 문제라고 생각을 못했다. 그냥 c를 배열에 먼저 넣고, a또는 b가 c보다 작거나 같다면 넣고, 그 차이를 넣고 중복을 제거하였다. ---> 틀렸습니다.
bfs로 푸는 이유
: 물을 옮길 수 있는 각각의 경우에 대해 탐색하기 위해
x->y, x->z, y->z, y->z, z->x, z->y
물통에 들어있을 수 있는 모든 경우의 수를 찾아서 첫번째 물통이 비어있을 때 세번째 물통의 양을 구한다.
1. 물통이 3개이지만 물의 총량은 고정이므로 a, b 두 물통만 체크하면 된다.
c는 저절로 정해진다.
2. visited 리스트를 2중 리스트로 작성한다.(a, b)
3. 처음에 (0,0)을 넣고 BFS
- a물통이 0일 때 c물통의 양을 리스트(답)에 넣어준다.
- x->y, x->z, y->z, y->z, z->x, z->y 의 6가지를 모두 탐색
- 조건에 맞다면 계속 탐색
- 물통에 들어있는 경우의 수를 구하는 방법
- 물을 옮기는 방법의 수를 찾는다.
(x : a에 담긴 물의 양, y : b에 담긴 물의 양, z : c에 담긴 물의 양)
: x->y, x->z, y->z, y->z, z->x, z->y 의 6가지
water = min(x, b-y)
: x에서 y로 옮길 물. x 전체를 옮기거나 b물통을 꽉 채운다.(한 물통이 비거나 다른 물통이 가득찰 때까지)pour(x-water, y+water)
: 옮긴 후의 x와 y상태를 큐에 저장.- c물통에 남아있는 물의 양 : z = c-x-y (물의 총량은 정해져있기 때문)
from collections import deque
def pour(x, y, visited, q):
if visited[x][y] == 0:
visited[x][y] = 1
q.append((x, y))
def bfs(a, b, c, visited):
q = deque()
q.append((0,0))
visited[0][0] = 1
ans = []
while q:
x, y = q.popleft()
z = c-x-y
if x == 0:
ans.append(z)
#x->y
if x>0 and y<b:
water = min(x, b-y)
pour(x-water, y+water, visited, q)
#x->z
if x>0 and z<c:
water = min(x, c-z)
pour(x-water, y, visited, q)
#y->x
if y>0 and x<a:
water = min(a-x, y)
pour(x+water, y-water, visited, q)
#y->z
if y>0 and z<c:
water = min(y, c-z)
pour(x, y-water, visited, q)
#z->x
if z>0 and x<a:
water = min(z, a-x)
pour(x+water, y, visited, q)
#z->y
if z>0 and y<b:
water = min(z, b-y)
pour(x, y+water, visited, q)
return ans
a, b, c = map(int, input().split())
visited = [[0]*(b+1) for _ in range(a+1)]
result = bfs(a, b, c, visited)
result.sort()
print(*result)