[알고리즘]BOJ 1052 물병

김상현·2022년 4월 9일
0

알고리즘

목록 보기
67/301
post-thumbnail
post-custom-banner

[BOJ] 1052 물병 바로가기

📍 문제

지민이는 N개의 물병을 가지고 있다. 각 물병에는 물을 무한대로 부을 수 있다. 처음에 모든 물병에는 물이 1리터씩 들어있다. 지민이는 이 물병을 또 다른 장소로 옮기려고 한다. 지민이는 한 번에 K개의 물병을 옮길 수 있다. 하지만, 지민이는 물을 낭비하기는 싫고, 이동을 한 번보다 많이 하기는 싫다. 따라서, 지민이는 물병의 물을 적절히 재분배해서, K개를 넘지 않는 비어있지 않은 물병을 만들려고 한다.

물은 다음과 같이 재분배 한다.

먼저 같은 양의 물이 들어있는 물병 두 개를 고른다. 그 다음에 한 개의 물병에 다른 한 쪽에 있는 물을 모두 붓는다. 이 방법을 필요한 만큼 계속 한다.

이런 제약 때문에, N개로 K개를 넘지않는 비어있지 않은 물병을 만드는 것이 불가능할 수도 있다. 다행히도, 새로운 물병을 살 수 있다. 상점에서 사는 물병은 물이 1리터 들어있다.

예를 들어, N=3이고, K=1일 때를 보면, 물병 3개로 1개를 만드는 것이 불가능하다. 한 병을 또다른 병에 부으면, 2리터가 들어있는 물병 하나와, 1리터가 들어있는 물병 하나가 남는다. 만약 상점에서 한 개의 물병을 산다면, 2리터가 들어있는 물병 두 개를 만들 수 있고, 마지막으로 4리터가 들어있는 물병 한 개를 만들 수 있다.


📍 입력

첫째 줄에 N과 K가 주어진다. N은 107보다 작거나 같은 자연수이고, K는 1,000보다 작거나 같은 자연수이다.


📍 출력

첫째 줄에 상점에서 사야하는 물병의 최솟값을 출력한다. 만약 정답이 없을 경우에는 -1을 출력한다.


📍 풀이

✍ 코드

from sys import stdin
N, K = map(int,stdin.readline().split())
D=[]
count = 1
result = 0
while(N): # N의 값을 2의 제곱수 중 가장 큰 값으로 분리하여 리스트에 저장
  if N == 1: # 현재 N의 값이 1일 경우
    D.append(1)
    break
  elif count >= N: # 현재 N의 값이 count 보다 작거나 같은 경우
    if count > N:
      count //= 2
    N -= count
    D.append(count)
    count = 1
  else: # 현재 N의 값이 count보다 클 경우
    count *= 2

while (len(D) > K): # 현재 배열의 원소의 수가 K보다 작거나 같을 때까지 반복
  if len(D) > 1 and D[-2] == D[-1]: # 현재 배열의 마지막 원소 2개가 같을 경우
    D.pop()
    D.append(2*D.pop())
    continue
  tmp1 = D.pop()
  tmp2 = D.pop()
  result += tmp2 - tmp1
  D.append(tmp2*2)
print(result)
profile
목적 있는 글쓰기
post-custom-banner

0개의 댓글