1052번: 물병 (acmicpc.net)

 

1052번: 물병

지민이는 N개의 물병을 가지고 있다. 각 물병에는 물을 무한대로 부을 수 있다. 처음에 모든 물병에는 물이 1리터씩 들어있다. 지민이는 이 물병을 또 다른 장소로 옮기려고 한다. 지민이는 한 번

www.acmicpc.net

1리터의 물이 들어있는 n개의 물병을 이용해 k개를 넘지 않는 비어있지 않은 물병을 만드는 문제이다. k개 이하의 물병을 만들기 위해서 상점에서 추가적으로 1리터의 물이 들어있는 n개의 물병을 사올 수 있는데, 이때 최소한으로 사오는 갯수를 구하여야 한다.

물은 아래와 같이 재분배한다.

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

.

#include <iostream>

using namespace std;

int test(int a) {
	int b = 0;
	while (1) {
		if (a == 1) {
			b++;
			break;
		}
		if (a % 2 == 1) {
			a--;
			b++;
		}
		else {
			a = a / 2;
		}
	}
	return b;
}

int main() {
	int n, k,a=0,b=1;
	cin >> n >> k;
	if (k >= n) {
		cout << 0;
	}
	else {
		while (1) {
			if (test(n)<=k) {
				break;
			}
			if (n % 2 == 0) {
				n = n / 2;
				b = b * 2;
			}
			else {
				n = n + 1;
				a = a + b;
			}
			
		}
		cout << a;
	}
}

 

나의 접근 방식은, 우선 같은 양의 물을 합칠 수 있을 만큼 합친 후, 홀수개가 되어 물병이 남게 될 경우 상점에서 추가로 물병을 사와 짝수개로 만들어주어 다시 합치는 방식으로 구현하였다. 예를 들어 100개의 물병이 있을 때 25개까지 합칠 수 있는데, 이 25개의 물병 각각의 물 양은 4리터가 될 것이다. 따라서 물병을 26개로 만들기 위해 상점에서 1리터 *4개의 물병을 사왔다.  이 과정에서 2,4,8,16,... 등 2의 제곱수만큼의 물병이 사올 때 마다 더해지게 된다.

루프 중 합쳐진 물병의 개수가 주어진 k개 이하로 나누어질 수 있는 경우 (이는 test함수를 구현하여 확인함. test의 경우 n을 2로 나눌 수 있을 만큼 나누고, 홀수가 된 경우 물병 하나를 빼는것과 동일하게 n에 -1을 해주었다. 최종적으로 n을 1까지 나누면 빼둔 물병에 n+1을 해주면 n개 물병을 합친 최솟값을 구할 수 있다.) 루프를 탈출하고 최종적으로 값을 출력하면 된다.

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

백준 1074번 - Z  (0) 2023.07.25
백준 1291번 - 이면수와 임현수  (0) 2023.07.24
백준 1002번 - 터렛  (0) 2023.07.23
백준 1051번 - 숫자 정사각형  (0) 2023.07.21
백준 2108번 - 통계학  (0) 2023.07.21

+ Recent posts