본문 바로가기

코딩테스트(자바)/문제풀이

백준 1052번 물병

728x90
반응형

문제

지민이는 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 이란 입력이 들어왔을 떄,

1L 물병 2개를 하나로 합치고, 남은 1L 물병을 하나 가지는게 최대로 나눈것이고 

총 2L 물병 1개와 1L 물병 한개를 가지고 있다. 여기서 이것을 1개의 물병으로 합치고 싶다면,

1L 물병을 한개를 구매하여 2L 물병으로 합치고, 다시 2L 물병 2개를 합치면 총 4L 물병 한개를 가지게 된다.

 

이렇게 입력을 해석하고 나면 익숙한 모양이 보이는데, 이는 즉 2진법이다.

총 물병의 개수를 2진법으로 나타내었을 때 1의 개수가 최대한으로 합친 물병의 갯수인것이다.

즉 N개의 물병에 몇개를 더하여서 2진법으로 나타내야지 '1'의 갯수가 K보다 낮거나 같을까?

가 문제가 물어보는 것이다.

 

이를 코드로 다시 나타내면

package backjun.Silver1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class 물병 {
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int N=0, K=0;
        try{
            String input = reader.readLine();
            N = Integer.parseInt(input.split(" ")[0]);
            K = Integer.parseInt(input.split(" ")[1]);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        int answer = 0;

        while (true){
            int cnt = 0;
            String binary = Integer.toBinaryString(N+answer);
            for(int i = 0; i< binary.length();i++){
                if(binary.charAt(i) == '1') cnt++;
            }
            if(cnt<=K) break;
            answer++;
        }

        System.out.println(answer);
    }
}

 

반응형