문제
지민이는 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을 출력한다.
예제 입력 1
3 1
예제 출력 1
1
예제 입력 2
13 2
예제 출력 2
3
예제 입력 3
1000000 5
예제 출력 3
15808
문제 이해
- 상점에서 구매하는 물병의 갯수를 최소한으로 하는 그리디 알고리즘 문제입니다.
문제 풀이
- 현재 가지고 있는 물병의 수를 이진수로 변환하여 1의 갯수를 파악합니다.
- 그림과 같이 각 물병의 갯수를 이진수로 나타냈을 때, 1의 갯수가 곧 상점에서 구매해야 하는 물병의 갯수가 됩니다.
- 10진수 기준으로 1씩 더해주며 해당 숫자를 2진수로 변환했을 때 1의 갯수를 세고, k보다 작거나 같아지면 종료합니다.
- 처음 시도했을 때 n의 십진수 수와 이진수 수를 각각 변환해서 따로 따로 작업하였으나 시간초과가 발생하였습니다.
- n을 기준으로 그때그때 2진수 변환을 시도하니 해결할 수 있었습니다.
코드
#백준 1052 물병
n, k = map(int, input().split())
count = 0
answer = -1
while True: #n이랑 bin_n을 함께 가져가기
if bin(n)[2:].count('1') <= k:
answer = count
break
n += 1
count += 1
print(answer)
'알고리즘 풀이 > Python' 카테고리의 다른 글
[Python] 꽃길 (백준 14620번 파이썬) (1) | 2023.10.15 |
---|---|
[Python] 헌내기는 친구가 필요해 (백준 21736번 파이썬) (2) | 2023.10.15 |
[Python] 계산기2 (SWEA D4 1223번 파이썬) (0) | 2023.10.14 |
[Python] 계산기1 (SWEA D4 1222번 파이썬) (0) | 2023.10.14 |
[Python] 미로 탐색 (백준 2178번 파이썬) (1) | 2023.10.13 |