chldkato

백준 2251 물통 (파이썬) 본문

백준

백준 2251 물통 (파이썬)

chldkato 2020. 2. 18. 00:53

https://www.acmicpc.net/problem/2251

 

2251번: 물통

각각 부피가 A, B, C(1≤A, B, C≤200) 리터인 세 개의 물통이 있다. 처음에는 앞의 두 물통은 비어 있고, 세 번째 물통은 가득(C 리터) 차 있다. 이제 어떤 물통에 들어있는 물을 다른 물통으로 쏟아 부을 수 있는데, 이때에는 한 물통이 비거나, 다른 한 물통이 가득 찰 때까지 물을 부을 수 있다. 이 과정에서 손실되는 물은 없다고 가정한다. 이와 같은 과정을 거치다보면 세 번째 물통(용량이 C인)에 담겨있는 물의 양이 변할 수도 있다.

www.acmicpc.net

1. 순열을 이용해서 물이 이동 가능한 경로를 저장해둔다

2. 물을 옮길 물통 번호(from)와 넣을 물통(to) 번호을 불러온다

3. 현재 0번 물통이 비었으면 2번 물통의 값을 ans에 기록한다

4. to가 넘치면 안되므로 한계치를 넘는지 검사한다

5. 조건에 맞게 from과 to의 물 양을 설정한다

6. bfs로 과정을 반복한 후 ans배열에 값이 있으면 해당 인덱스를 출력한다

from collections import deque
from itertools import permutations
import sys, copy

input = sys.stdin.readline

def bfs(x, y, z):
    q.append([x, y, z])
    check.append([x, y, z])
    while q:
        k = q.popleft()
        if k[0] == 0:
            ans[k[2]] = 1
        for i in range(len(t)):
            nfrom = t[i][0]
            nto = t[i][1]
            nk = copy.deepcopy(k)
            if k[nfrom] + k[nto] > limit[nto]:
                nk[nfrom] = k[nfrom] + k[nto] - limit[nto]
                nk[nto] = limit[nto]
            else:
                nk[nfrom] = 0
                nk[nto] = k[nfrom] + k[nto]
            if nk not in check:
                check.append(nk)
                q.append(nk)

a, b, c = map(int, input().split())
q, check, limit = deque(), [], [a, b, c]
ans = [0 for _ in range(c+1)]
t = list(permutations([0, 1, 2], 2))

bfs(0, 0, c)

for i in range(c+1):
    if ans[i] == 1:
        print(i, end=' ')

Comments