- 문제 : https://www.acmicpc.net/problem/14867

 

문제 이해

- 물통 a, b 가 있는데 몇 가지 방식에 의해 물을 채우고 비울 수 있다.

- 물통에 있는 물을 옮기는 규칙은 다음과 같다.

  1. 한 번에 가득 채우거나, 비울 수 있다.

  2. a -> b, b -> a로 물을 옮길 수 있다.

    a -> b인 상황을 예시로, b에 남은 공간에 따라 a가 줄 수 있는 물의 양은 달라진다.

    b의 남은 공간 > a 물의 양 일 때는 a에 있는 모든 물을 b에 옮길 수 있다.

    b의 남은 공간 < a 물의 양 일 때는 b의 남은 공간만큼만 a에서 옮길 수 있다. 

- 위의 움직임을 모두 bfs로 진행하면 된다. 1차 분기문으로 단순하게 나눠서 진행하면 될거라고 생각했지만, 케이스가 세세하게 생각이 안나서 좀 헤맸다. 

- 물통 비우기, 물통 가득 채우기, 물 옮기기 를 물통 a와 물통 b의 관점에서 생각하고 케이스를 짜면 쉽게 짤 수 있다.

 

풀이 로직

- 물통 a, b의 용량과 목표 용량을 입력 받고 중복 방문하지 않기 위해서 visit를 set으로 설정한다. 

  visit는 일차원 배열로 그 안에 원소가 있는 경우 방문한 것으로 생각한다. 

- while문으로 bfs를 진행하는데, 방문한 노드가 target이라면 answer를 갱신한 뒤 break 한다.

- 아직 target에 도착하지 못했다면 A 물통을 비웠을 때, 가득 채웠을 때, B 물통으로 물을 옮길 때를 분기문으로 작성하고, queue와 visit    처리를 해준다. 마찬가지로 B 물통을 비웠을 때, 가득 채웠을 때, A 물통으로 물을 옮길 때를 분기문으로 작성하고, queue와 visit 처리를    해준다. 

 

정답 풀이 

a, b, target_a, target_b = map(int, input().split())

queue = [[0, 0, 0]] # a에 있는 물의 양, b에 있는 물의 양, 연산횟수
visit = set()
visit.add((0, 0))

answer = -1
while queue:
    x, y, times = queue.pop(0)
    
    if x == target_a and y == target_b:
        answer = times
        break
    
    if (a, y) not in visit:
        visit.add((a, y))
        queue.append([a, y, times + 1])
    if (x, b) not in visit:
        visit.add((x, b))
        queue.append([x, b, times + 1])
    if (0, y) not in visit:
        queue.append([0, y, times + 1])
        visit.add((0, y))
    if (x, 0) not in visit:
        queue.append([x, 0, times + 1])
        visit.add((x, 0))
    
    if x + y >= b:
        if (x - b + y, b) not in visit:
            visit.add((x + y - b, b))
            queue.append([x + y - b, b, times + 1])
    else:
        if (0, x + y) not in visit:
            visit.add((0, x + y))
            queue.append([0, x + y, times + 1])

    if x + y >= a:
        if (a, x + y - a) not in visit:
            queue.append([a, x + y - a, times + 1])
            visit.add((a, x + y - a))
    else:
        if (x + y, 0) not in visit:
            queue.append([x + y, 0, times + 1])
            visit.add((x + y, 0))
            
print(answer)

 

 

참고한 블로그 : https://kingsol.tistory.com/10

'백준 > Search' 카테고리의 다른 글

[bfs/백준] 1525번 : 퍼즐  (0) 2023.05.31
[bfs/백준] 1039번 : 교환  (0) 2023.05.26
[bfs/백준] 9019번 : DSLR  (0) 2023.05.26
[bfs/백준] 16397번 : 탈출  (0) 2023.05.25
[bfs/백준] 3055번 : 탈출  (0) 2023.05.25

+ Recent posts