Baekjoon Online Judge
문제
지민이는 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을 출력한다.
예제 입력 | 예제 출력 |
3 1 | 1 |
13 2 | 3 |
1000000 5 | 15808 |
풀이
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt(); // N개의 물병
int K = in.nextInt(); // 한 번에 옮길 수 있는 물병 K개
int shop = 0; // 구매해야 하는 물병의 수
while (true) {
String solo = Integer.toBinaryString(N); // N을 2진수로 변환
int bottle = 0; // 물병의 수
int idx = -1;
// 현재 옮겨야하는 물병의 수
for (int i = 0; i < solo.length(); i++)
if (solo.charAt(i) == '1') {
bottle++;
if (idx == -1) idx = i;
}
// 상점에서 사야하는 물병의 최솟값 찾기
if (bottle <= K) break;
else {
N += ((int)Math.pow(2, idx));
shop += ((int)Math.pow(2, idx));
}
}
// 출력
System.out.println(shop);
}
}
입력 받은 물병의 개수 N을 2진수로 바꾸면 하나 남은 물병이 물이 몇 리터 들어있는지 알 수 있다. 물병의 수를 줄이기 우해서는 이 혼자 남은 물병을 줄여야 한다.
// 현재 옮겨야하는 물병의 수
for (int i = 0; i < solo.length(); i++)
if (solo.charAt(i) == '1') {
bottle++;
if (idx == -1) idx = i;
}
이 부분에서 물병의 수를 센다. 물병의 수를 줄일 때 1리터짜리 물병을 구매를 효율적으로 하기 위해 가장 적은 양이 들어있는 하나 남은 물병의 인덱스를 저장한다.
// 상점에서 사야하는 물병의 최솟값 찾기
if (bottle <= K) break;
else {
N += ((int)Math.pow(2, idx));
shop += ((int)Math.pow(2, idx));
}
만약 물병의 수가 한 번에 옮길 수 있는 수가 되면 반복문을 종료하지만 그렇지 않다면 상점에서 아까 저장한 인덱스를 이용해서 물병을 구매한다. 여기서 구매하는 물병의 개수는 아래와 같다.
ex)
idx 0 1 2 3 4 5 6 즉 2의 idx승이다.
1 2 4 8 16 32 64
'백준 > JAVA' 카테고리의 다른 글
[Baekjoon/JAVA] 2420번 - 사파리월드 (0) | 2022.08.20 |
---|---|
[Baekjoon/JAVA] 1058번 - 친구 (0) | 2022.08.14 |
[Baekjoon/JAVA] 1049번 - 기타줄 (0) | 2022.08.06 |
[Baekjoon/JAVA] 1026번 - 보물 (0) | 2022.08.06 |
[Baekjoon/JAVA] 1652번 - 누울 자리를 찾아라 (0) | 2022.07.30 |