# 2251 물통
# A,B,C
# 앞의 두 물통은 비어 있고, 세번째 물통은 가득 차 있다.
# A 물통이 비어있을때 세번째 물통에 담겨 있을 수 있는 물의 양을 구해내시오.
import collections
max_Bowl = list(map(int,input().split()))
current_bowl = [0,0,max_Bowl[2]]
visited = [[[False]*(max_Bowl[2]+1) for _ in range(max_Bowl[1]+1)] for _ in range(max_Bowl[0]+1)]
# A,B,C
que = collections.deque()
que.appendleft((0,0,max_Bowl[2]))
result = set()
result.add(max_Bowl[2])
while que:
cureent_water = que.popleft()
if visited[cureent_water[0]][cureent_water[1]][cureent_water[2]]:
continue
if cureent_water[0] == 0:
result.add(cureent_water[2])
visited[cureent_water[0]][cureent_water[1]][cureent_water[2]] = True
# A->B
if cureent_water[0]+cureent_water[1] >= max_Bowl[1]:
que.append((cureent_water[0]+cureent_water[1]-max_Bowl[1],max_Bowl[1],cureent_water[2]))
else:
que.append((0,cureent_water[0]+cureent_water[1],cureent_water[2]))
# A->C
if cureent_water[0]+cureent_water[2] >= max_Bowl[2]:
que.append((cureent_water[0]+cureent_water[2]-max_Bowl[2],cureent_water[1],max_Bowl[2]))
else:
que.append((0,cureent_water[1],cureent_water[0]+cureent_water[2]))
# B->C
if cureent_water[1]+cureent_water[2] >= max_Bowl[2]:
que.append((cureent_water[0],cureent_water[1]+cureent_water[2]-max_Bowl[2],max_Bowl[2]))
else:
que.append((cureent_water[0],0,cureent_water[1]+cureent_water[2]))
# B->A
if cureent_water[1]+cureent_water[0] >= max_Bowl[0]:
que.append((max_Bowl[0],cureent_water[1]+cureent_water[0]-max_Bowl[0],cureent_water[2]))
else:
que.append((cureent_water[1]+cureent_water[0],0,cureent_water[2]))
# C->A
if cureent_water[2] + cureent_water[0] >= max_Bowl[0]:
que.append((max_Bowl[0],cureent_water[1],cureent_water[2]+cureent_water[0]-max_Bowl[0]))
else:
que.append((cureent_water[2]+cureent_water[0],cureent_water[1],0))
# C->B
if cureent_water[2] + cureent_water[1] >= max_Bowl[1]:
que.append((cureent_water[0],max_Bowl[1],cureent_water[2]+cureent_water[1]-max_Bowl[1]))
else:
que.append((cureent_water[0],cureent_water[2]+cureent_water[1],0))
result = sorted(list(result))
print(*result)
처음에 풀때 난잡하다. 똑같이 반복되는것을 계쏙 반복해주었다.
A->B,
A->C
B->C
B->A
C->A
C->B
의 과정을 거쳐주면서 방문하지 않은 경우에만 하는 방식으로 했다.
이렇게 하니 단순반복을 계속해서 쓰면서도 알아보기 힘들었다.
A,B,C = map(int,input().split())
def custom_append(a,b,c):
global visited,stack,result
if (a,b,c) not in visited:
visited.add((a,b,c))
stack.append((a,b,c))
if a == 0:
result.add(c)
def move_bowl(origin,target,target_max):
if origin+target >= target_max:
origin = origin+target- target_max
target = target_max
else:
target = origin + target
origin = 0
return (origin,target)
visited = set()
visited.add((0,0,C))
stack = [(0,0,C)]
result = set()
result.add(C)
while stack:
ca,cb,cc = stack.pop()
if ca:
# A->B
na,nb = move_bowl(ca,cb,B)
custom_append(na,nb,cc)
# A->C
na,nc = move_bowl(ca,cc,C)
custom_append(na,cb,nc)
if cb:
# B->C
nb,nc = move_bowl(cb,cc,C)
custom_append(ca,nb,nc)
# B->A
nb,na = move_bowl(cb,ca,A)
custom_append(na,nb,cc)
if cc:
# C->A
nc,na = move_bowl(cc,ca,A)
custom_append(na,cb,nc)
# C->B
nc,nb = move_bowl(cc,cb,B)
custom_append(ca,nb,nc)
result = sorted(list(result))
print(*result)
좀 더 깔끔하게 바뀐 풀이방식이다.
물을 옮기는 과정을 하나의 함수로 만들어주었고, stack에 추가해주고 방문표시를 해주는것도 하나의 함수로 만들어줬다.
이렇게 하니, 본문에는 간단하게 남았고, 불필요한 코드를 반복해서 쓸필요성이 없어졌다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 12851 숨바꼭질 2 (0) | 2021.01.25 |
---|---|
[BOJ/백준] 2133 타일 채우기 (0) | 2021.01.24 |
[BOJ/백준] 2624 동전 바꿔주기 (0) | 2021.01.22 |
[BOJ/백준] 17142 연구소3 (0) | 2021.01.22 |
[BOJ/백준] 1946 신입 사원 (0) | 2021.01.22 |