본문 바로가기

알고리즘

백준 1052. 물병 (C++)

https://www.acmicpc.net/problem/1052

 

1052번: 물병

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

www.acmicpc.net

 

여기서 POINT는,

 

a. while문 안에서 계속 N/2를 한다 (조건: N의 몫이 0이 될 때 까지)

b. N%2 == 1 or 0 이므로, 1일 경우에 Cnt ++;   -> 합쳐지지 못한 물병의 갯수를 카운트 하는 과정 (맨 마지막에 N/2==0 즉, 다 합쳐진 물병의 갯수(1)도 카운트 포함한 값임)

c. N의 몫이 0이 되면 while문을 빠져나와 여태까지 합쳐지지 못한 물병의 갯수를 반환

d. N의 갯수를 늘려가며 (->이게 결국 물병을 사는 과정) Cnt <=K 를 만족할 때 까지 진행

#include<iostream>
 
#define endl "\n"
using namespace std;
 
int N, K, Answer;
 
void Input()
{
    cin >> N >> K;	// 물병 갯수: N, 한 번에 들고 갈 수 있는 갯수: K
}
 
int Add_Water(int x)
{
    int Cnt = 0;
    while (x > 0)
    {
        //5면
        // 2가 되고 -> 1이 됨
        if (x % 2 == 1) Cnt++;
        x = x / 2;
    }
    return Cnt;
}
 
void Solution()
{
    if (N <= K) cout << 0 << endl; // 물병 갯수 < 한 번에 들고갈 수 있는 물병 갯수 => 검사할 필요 X
  
  	else
    {
        while (1)
        {
            int Temp_Result = Add_Water(N);
            if (Temp_Result <= K) break; // 왜 K랑 같은경우도 포함되냐? 1%2==1 까지도 계산하므로
 
            Answer++;
            N++;
        }
        cout << Answer << endl;
    }
 
}
 
void Solve()
{
    Input();
    Solution();
}
 
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    Solve();
 
    return 0;
}

 

출처 - https://yabmoons.tistory.com/199